Day 2 part 1

main
Ashelyn Dawn 1 year ago
parent c8d2d37918
commit 4dcda3d0b9

@ -0,0 +1,304 @@
(;
; Advent of Code 2022: Day 2, in wasm
; by Ashelyn Dawn
;)
(module
(import "console" "log1" (func $log1 (param i32)))
(import "console" "log2" (func $log2 (param i32) (param i32)))
(import "console" "log3" (func $log3 (param i32) (param i32) (param i32)))
(memory (export "memory") 10)
(global $readLoc (mut i32) (i32.const 0))
(global $inputEnd (mut i32) (i32.const 0))
(global $outputStart (mut i32) (i32.const 0))
(global $outputEnd (mut i32) (i32.const 0))
(func (export "part1") (result i32)
(local $currentScore i32)
(local $lastRead i32)
call $initRead
loop $readLoop
call $readLine
;; check to see if we've hit the end
local.tee $lastRead
i32.eqz
if
call $initWrite
local.get $currentScore
call $writeNum
call $closeWrite
return
end
local.get $lastRead
call $getScore
local.get $currentScore
i32.add
local.set $currentScore
br $readLoop
end
unreachable
)
(func (export "part2") (result i32)
i32.const 0
)
(func $initRead
;; Read input length
i32.const 0
i32.load
;; Store input end byte
i32.const 4
i32.add
global.set $inputEnd
;; Set up start read location
i32.const 4
global.set $readLoc
)
(func $initWrite
(local $dup i32)
;; set up output end pointer
global.get $inputEnd
i32.const 4
i32.add
global.set $outputStart
global.get $outputStart
global.set $outputEnd
)
(func $closeWrite (result i32)
;; get the length to return
global.get $inputEnd
global.get $outputEnd
global.get $outputStart
i32.sub
i32.store
;; return location of length
global.get $inputEnd
)
(func $getScore (param $theirs i32) (param $ours i32) (result i32)
(local $diff i32)
;; get diff value
local.get $theirs
local.get $ours
i32.sub
local.set $diff
block $conditions
;; if it's a draw
local.get $diff
i32.eqz
if
i32.const 3 ;; 3 points for draw
local.get $ours ;; points for what you played
i32.add
local.set $diff
br $conditions
end
;; check which is greater
local.get $diff
i32.const 0
i32.lt_s
if ;; diff is negative, ours is bigger than theirs
local.get $diff
i32.const -2
i32.eq
if ;; if the diff is two, we did scissors (3), they did rock (1); they win
local.get $ours
local.set $diff
br $conditions
else ;; diff of one, we won (scissors beats paper, paper beats rock)
i32.const 6
local.get $ours
i32.add
local.set $diff
br $conditions
end
else ;; diff is positive, theirs is bigger than ours
local.get $diff
i32.const 2
i32.eq
if ;; if the diff is two, we did rock (1), they did scissors (3), we win
i32.const 6
local.get $ours
i32.add
local.set $diff
br $conditions
else ;; diff of one, they won
local.get $ours
local.set $diff
br $conditions
end
end
end
(; local.get $theirs ;)
(; local.get $ours ;)
(; local.get $diff ;)
(; call $log3 ;)
local.get $diff
)
(func $readLine (result i32 i32)
call $readChar
call $readChar
)
(func $readChar (result i32)
(local $charcode i32)
;; Make sure we're still inside the input area
block $readLocCheck
global.get $readLoc
global.get $inputEnd
i32.lt_u
br_if $readLocCheck
i32.const 0
return
end
;; Read the character
global.get $readLoc
i32.load8_u
local.set $charcode
;; increment read location
global.get $readLoc
i32.const 1
i32.add
global.set $readLoc
local.get $charcode
call $translateChar
local.tee $charcode
;; if we didn't find a valid char, keep reading until we do
i32.eqz
if
call $readChar
return
end
local.get $charcode
return
)
(func $translateChar (param $input i32) (result i32)
local.get $input
i32.const 65 ;; A
i32.eq
if
i32.const 1
return
end
local.get $input
i32.const 66 ;; B
i32.eq
if
i32.const 2
return
end
local.get $input
i32.const 67 ;; C
i32.eq
if
i32.const 3
return
end
local.get $input
i32.const 88 ;; X
i32.eq
if
i32.const 1
return
end
local.get $input
i32.const 89 ;; Y
i32.eq
if
i32.const 2
return
end
local.get $input
i32.const 90 ;; Z
i32.eq
if
i32.const 3
return
end
i32.const 0
return
)
(func $writeNum (param $number i32)
(local $digit i32)
;; store lowest digit
local.get $number
i32.const 10
i32.rem_u
local.set $digit
;; divide number by 10
local.get $number
i32.const 10
i32.div_u
local.tee $number
;; base case
i32.eqz
if
local.get $digit
call $writeDigit
return
end
;; recurse (to print other digits)
local.get $number
call $writeNum
;; print our digit
local.get $digit
call $writeDigit
)
(func $writeDigit (param $digit i32)
global.get $outputEnd
local.get $digit
i32.const 48
i32.add
i32.store
global.get $outputEnd
i32.const 1
i32.add
global.set $outputEnd
)
)

@ -59,7 +59,15 @@ async function loadDay(dayNum) {
write_debug_names: true
})
const { instance } = await WebAssembly.instantiate(codeBuffer)
const moduleImports = {
console: {
log1: (a) => console.log(a),
log2: (a, b) => console.log(a, b),
log3: (a, b, c) => console.log(a, b, c)
}
}
const { instance } = await WebAssembly.instantiate(codeBuffer, moduleImports)
wasmInstance = instance
codeView.innerHTML = wasmText
@ -122,18 +130,20 @@ function runDay() {
let part1run = null, part2run = null
try {
part1run = runPart('part1', inputTextArea, outputTextArea1).toFixed(2)
} catch { }
} catch (e) { console.error(e) }
try {
part2run = runPart('part2', inputTextArea, outputTextArea2).toFixed(2)
} catch { }
} catch (e) { console.error(e) }
if (part1run && part2run) {
output.innerText = `success; part 1 runtime: ${part1run}ms, part 2 runtime: ${part2run}ms`
} else if (part1run) {
output.innerText = `partial success; part 1 runtime: ${part1run}ms, part 2: crashed`
} else {
} else if (part2run) {
output.innerText = `partial success; part 1: crashed, part 2 runtime: ${part2run}ms`
} else {
output.innerText = 'running wasm code failed'
}
}

Loading…
Cancel
Save