Created
January 15, 2017 21:05
-
-
Save russross/23f06896acc99a5328cde8a3083e27cf to your computer and use it in GitHub Desktop.
ARMv6 assembly solution to a math puzzle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ ARMv6 solution to the puzzle: | |
@ | |
@ 13 JASONs when added equal FRIDAY. | |
@ Use only the digits 0 to 9. | |
@ No leading zeros. Each letter maps to one and | |
@ only one number. | |
@ | |
@ JASON + JASON + | |
@ JASON + JASON + JASON + | |
@ JASON + JASON + JASON + | |
@ JASON + JASON + JASON + | |
@ JASON + JASON = FRIDAY | |
@ | |
@ Note: this solution assumes each digit can only be used | |
@ once, i.e., there is a bijection between the digits | |
@ (0..9) and the letters (j,a,s,o,n,f,r,i,d,y). | |
@ | |
@ It works by cycling through all possible values for JASON | |
@ (10,000 up to 99,999) and computing 13 * JASON for each one. | |
@ It then converts each number to a string and checks the results | |
@ to see if they match the constraints. | |
@ | |
@ Compile on a Raspberri Pi running Raspbian using: | |
@ as -g jasonfriday.s -o jasonfriday.o | |
@ ld jasonfriday.o -o jasonfriday | |
@ | |
@ Russ Ross (github user russross), January 15, 2017 | |
.global _start | |
.equ sys_exit, 1 | |
.equ sys_write, 4 | |
.equ stdout, 1 | |
.data | |
result: .ascii "jason = " | |
jasontxt: .space 5 | |
.ascii ", friday = " | |
fridaytxt: .space 7 | |
.equ resultlen, .-result | |
.text | |
_start: | |
@ r4: jason | |
@ r5: friday | |
@ no leading zeros allows, so start | |
@ with jason = 10000 | |
ldr r4, =10000 | |
b 5f | |
1: | |
@ compute friday = 13 * jason | |
add r5, r4, r4, lsl #1 | |
add r5, r4, r5, lsl #2 | |
@ convert json to text | |
ldr r0, =jasontxt | |
mov r1, r4 | |
bl itoa | |
@ must be exactly 5 digits long | |
cmp r0, #5 | |
bne 4f | |
@ convert friday to text | |
ldr r0, =fridaytxt | |
mov r1, r5 | |
bl itoa | |
@ must be exactly 6 digits long | |
cmp r0, #6 | |
bne 4f | |
@ 'a' in jason and in friday must match | |
ldr r0, =jasontxt | |
ldrb r1, [r0, #1] | |
ldr r0, =fridaytxt | |
ldrb r2, [r0, #4] | |
cmp r1, r2 | |
bne 4f | |
@ check that each digit is used exactly once | |
@ set bit #n when we find digit n | |
@ end result should be the number 1111111111 | |
mov r0, #0 | |
mov r1, #0 | |
mov ip, #1 | |
ldr r2, =jasontxt | |
2: | |
ldrb r3, [r2,r1] | |
sub r3, r3, #'0' | |
orr r0, r0, ip, lsl r3 | |
add r1, r1, #1 | |
cmp r1, #5 | |
blt 2b | |
mov r1, #0 | |
ldr r2, =fridaytxt | |
3: | |
ldrb r3, [r2,r1] | |
sub r3, r3, #'0' | |
orr r0, r0, ip, lsl r3 | |
add r1, r1, #1 | |
cmp r1, #6 | |
blt 3b | |
ldr r1, =0b1111111111 | |
cmp r0, r1 | |
bne 4f | |
@ found a solution, so print result | |
@ append a newline | |
mov r0, #'\n' | |
ldr r1, =fridaytxt | |
strb r0, [r1,#6] | |
mov r0, #stdout | |
ldr r1, =result | |
mov r2, #resultlen | |
mov r7, #sys_write | |
svc #0 | |
4: | |
add r4, r4, #1 | |
5: | |
ldr r0, =100000 | |
cmp r4, r0 | |
blt 1b | |
@ exit | |
mov r0, #0 | |
mov r7, #sys_exit | |
svc #0 | |
@ itoa(buffer, n) -> number of bytes written | |
itoa: | |
.equ div10_magic, 0xcccccccd | |
push {r4-r6,lr} | |
@ r0: buffer | |
@ r1: n | |
@ r2: length of output | |
@ r3: division magic number | |
@ r4: digit | |
@ r5: new n | |
ldr r3, =div10_magic | |
mov r2, #0 | |
1: | |
@ do a division by 10 | |
umull r4, r5, r3, r1 @ multiply by magic number | |
mov r5, r5, lsr #3 @ shift: new_n is in r5 | |
add r4, r5, r5, lsl #2 @ compute new_n*5 | |
sub r4, r1, r4, lsl #1 @ remainder = n - new_n*5*2 | |
add r4, r4, #'0' @ convert to digit | |
strb r4, [r0,r2] @ store in buffer | |
add r2, r2, #1 @ length++ | |
subs r1, r5, #0 @ n = newn and compare with 0 | |
bgt 1b | |
@ reverse the string | |
@ r0: first | |
@ r1: last | |
@ r2: length of output | |
@ r3: firstchar | |
@ r4: lastchar | |
add r1, r0, r2 | |
sub r1, r1, #1 | |
bal 3f | |
2: | |
ldrb r3, [r0] | |
ldrb r4, [r1] | |
strb r3, [r1], #-1 | |
strb r4, [r0], #1 | |
3: | |
cmp r0, r1 | |
blt 2b | |
mov r0, r2 | |
pop {r4-r6,pc} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment