a-conjecture-of-mine

An exercise on polyglossy: the same problem solved on multiple languages

commit cdde6db78daac54b57f4db8cb2f389c5a2fa5139
parent f0b814c4e433cb097c83c1a7f80adf7aa74a3094
Author: Pablo Escobar Gaviria <gark.garcia@protonmail.com>
Date:   Sun, 29 Dec 2019 12:36:49 -0200

Cleaned the DOS x86 implementation.

Diffstat:
M.gitignore | 2--
MElixir/digital_sum.ex | 5+++++
Rhla/conjecture.hla -> Extra/High Level Assembly/conjecture.hla | 0
AExtra/x86/PROGRAM.ASM | 193+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dx86/PROGRAM.ASM | 411-------------------------------------------------------------------------------
5 files changed, 198 insertions(+), 413 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -4,9 +4,7 @@
 *.IMG
 *.beam
 bin
-bin/
 build
 Statistics
 Latex
-Q#
 Cuda
diff --git a/Elixir/digital_sum.ex b/Elixir/digital_sum.ex
@@ -1,3 +1,8 @@
+# The following program is a simple test for the following conjecture:
+
+# Let S: N -> N be the sum of the digits of a positive integer.
+# For all A and B in N, S(A + B) = S(A) + S(B) - 9k, where k is an integer.
+
 defmodule Conjecture do
   def main max, n_processes do
     if max < 0 or n_processes <= 0 do
diff --git a/hla/conjecture.hla b/Extra/High Level Assembly/conjecture.hla
diff --git a/Extra/x86/PROGRAM.ASM b/Extra/x86/PROGRAM.ASM
@@ -0,0 +1,193 @@
+.model tiny
+
+.stack 1000h
+
+.data
+        max        dw 0
+        a          dw 0
+        b          dw 0
+        sumAB      dw 0
+        sumA       dw 0
+        sumB       dw 0
+
+        sums_cache dw 25000 DUP(0)
+
+.code
+        org 100h
+
+start:
+        mov  ax, @data
+        mov  ds, ax
+
+        call read_uint ; Retrieve user input  
+
+        call cache_sums
+        call counterexpl
+
+read_uint:
+        push si
+
+        ; Move the start of the command-line tail to `si`
+        mov  si, ds
+        add  si, 81h
+
+read_loop:
+        ; Read a character from the command-line tail
+        mov  bx, [si]
+
+        ; Jump out of the loop at the end of the first arg
+        cmp  bx, 20h
+        jmp  read_end
+        cmp  bx, 0dh
+        jmp  read_end
+
+        ; Check if it's a numeric character
+        cmp  bx, 30h
+        jb   invalid_input
+        cmp  bx, 39h
+        ja   invalid_input
+
+        ; Convert the character code into a decimal digit
+        sub  bx, 30h
+
+        ; ax = ax * 10 + bx
+        push cx
+        mov  cx, 10
+        mul  cx
+        pop  cx
+        add  ax, bx
+
+        ; Increment the pointer to the argument string and keep looping
+        inc  si
+        jmp  read_loop
+
+read_end:
+        mov  max, ax
+        pop  si
+        ret
+
+cache_sums:
+        mov  si, offset sums_cache
+
+        mov  ax, max
+        mov  bx, 2
+        mul  bx
+        mov  bx, ax
+
+        mov  ax, 0
+cache_sums_loop:
+        push  bx
+        push  ax
+        call  sum_digits
+        mov   [si], bx
+
+        pop  ax
+        add  si, 2
+        inc  ax
+
+        pop  bx
+        cmp  ax, bx
+        jb   cache_sums_loop
+        ret
+
+; Iterate `a` from 0 to `max`
+counterexpl:
+        mov  ax, a
+        call iter
+
+        inc  ax
+        mov  a, ax
+        cmp  ax, max
+        jbe  counterexpl
+
+        call ok
+
+; Iterate `b` from `a` to 0
+iter:
+        mov  ax, a
+        mov  b, ax
+
+iter_loop:
+        call test_pair
+
+        dec  b
+        mov  ax, b
+        cmp  ax, 0
+        jae  iter_loop
+        ret
+
+test_pair:
+        ; Calculate S(A + B) and store it in sumAB
+        mov  si, offset sums_cache
+        add  si, a
+        add  si, b
+        mov  ax, [si]
+        mov  sumAB, ax
+        mov  ax, si
+
+        ; Calculate S(A) and store it in sumA
+        mov  si, offset sums_cache
+        add  si, a
+        mov  ax, [si]
+        mov  sumA, ax
+
+        ; Calculate S(B) and store it in sumB
+        mov  si, offset sums_cache
+        add  si, b
+        mov  ax, [si]
+        mov  sumB, ax 
+
+
+        ; Calculate S(a + b) - S(a) - S(b) in ax
+        mov  ax, sumAB
+        sub  ax, sumA
+        sub  ax, sumB
+
+        mov  cx, 9 ; Set the devident to 9
+        mov  dx, 0 ; Clear the register where the rest will be stored
+        div  cx
+
+        cmp  dx, 0
+        jne  fail
+
+        ret
+
+sum_digits:
+        mov  cx, 10 ; Store the devident in cx
+        mov  bx, 0 ; Clear the register where the result will be stored
+sum_loop:
+        mov  dx, 0 ; Clear the rest of the division
+
+        div  cx ; Divide ax by cx
+        add  bx, dx ; Add the rest of the division ax/cx to bx
+
+        ; Loop until ax equals 0
+        cmp  ax, 0
+        ja   sum_loop
+        ret
+
+;; Exit with exit-code 0
+ok:
+        mov  al, 0
+        call quit
+        ret
+
+;; Exit with exit-code 1
+fail:
+        mov  al, 1
+        call quit
+        ret
+
+;; Exit with exit-code 2
+invalid_input:
+        mov  al, 2
+
+        call quit
+        ret
+
+;; Exit with exit-code `al`  
+quit:
+        mov  ah, 4ch
+        int  21h
+        ret
+end start
diff --git a/x86/PROGRAM.ASM b/x86/PROGRAM.ASM
@@ -1,411 +0,0 @@
-.model tiny
-
-.stack 1000h
-
-.data
-        input      db 8 DUP(0)
-        invalid    db "' is not a natural number!", 0dh, 0ah, 0dh, 0ah, "$"
-        too_big    db " is too big!", 0dh, 0ah, 0dh, 0ah, "$"
-
-        max        dw 0
-        a          dw 0
-        b          dw 0
-        sumAB      dw 0
-        sumA       dw 0
-        sumB       dw 0
-
-        sums_cache dw 25000 DUP(0)
-
-        start_time dw 0
-        end_time   dw 0
-
-        proof      db 0dh, 0ah, "The conjecture is proved for all natural numbers smaller or equals to $"
-        counter    db 0dh, 0ah, "The conjecture is disproved! Here's a counterexample: ($"
-        loading    db 0dh, 0ah, "LOADING. . .$"
-        loaded     db 0dh, 0ah, "LOADED. . . in $"
-
-        intro1     db 0dh, 0ah, "This program is a simple test for the following conjecture:", 0dh, 0ah, "$"
-        intro2     db 0dh, 0ah, "Let S: N -> N be the sum of the digits of a positive integer.", 0dh, 0ah, "$"
-        intro3     db "For all A and B in N, S(A + B) = S(A) + S(B) - 9k, where k is an integer.", 0dh, 0ah, "$"
-        intro4     db 0dh, 0ah, "What value would you like to test the conjecture for? $"
-
-.code
-        org 100h
-
-start:
-        mov ax, @data
-        mov ds, ax
-
-        ; Print the intro messages to the screen
-        mov ah, 9h
-        mov dx, offset intro1
-        int 21h
-        mov dx, offset intro2
-        int 21h
-        mov dx, offset intro3
-        int 21h
-        mov dx, offset intro4
-        int 21h
-
-        call read_uint ; Retrieve user input  
-
-        ; Set the start_time variable
-        mov si, offset start_time
-        call get_time
-
-        mov ah, 9h
-        mov dx, offset loading
-        int 21h
-
-        call cache_sums
-        call iter
-
-read_uint:
-        ; Load the user input into the input
-        mov ax, cs
-        mov ds, ax
-        mov input[0], 6 ; Configure the input length
-        mov dx, offset input
-        mov ah, 0ah
-        int 21h
-
-        ; Print '\n'
-        mov ah, 2h
-        mov dx, 0dh
-        int 21h
-        mov dx, 0ah
-        int 21h
-
-        ; Move si to the to adress of the first character in the input
-        mov si, offset input
-        add si, 2
-
-        mov ax, 0 ; Initialize the register where the result will be stored
-        mov cx, 1 ; Initialize a counter
-
-read_loop:
-        mov bx, 0 ; Clear bx
-        mov bl, [si] ; Read a character into bx
-        inc cx ; Increment the counter
-        inc si ; Increment the source index
-
-        ; Check if it's a numeric character
-        cmp bl, 30h
-        jb short invalid_input
-        cmp bl, 39h
-        ja short invalid_input
-
-        ; Convert the character code into a decimal digit
-        sub bl, 30h
-
-        ; ax = ax * 10 + bx
-        push cx
-        mov cx, 10
-        mul cx
-        pop cx
-        add ax, bx
-
-        cmp ax, 12500
-        ja short input_too_big
-
-        ; Jump if the counter is still smaller than the input length
-        cmp cl, input[1]
-        jbe short read_loop
-
-        mov max, ax
-        ret
-
-invalid_input:
-        mov ah, 2h
-
-        ; Print '\''
-        mov dx, 27h
-        int 21
-
-        mov si, offset input
-        call print_buffer
-
-        ; Print the rest of the message
-        mov ah, 9h
-        mov dx, offset invalid
-        int 21h
-
-        call quit
-        ret
-
-input_too_big:
-        mov si, offset input
-        call print_buffer
-
-        mov ah, 9h
-        mov dx, offset too_big
-        int 21h
-
-        call quit
-        ret
-
-cache_sums:
-        mov si, offset sums_cache
-
-        mov ax, max
-        mov bx, 2
-        mul bx
-        mov bx, ax
-
-        mov ax, 0
-cache_sums_loop:
-        push bx
-        push ax
-        call sum_digits
-        mov [si], bx
-
-        pop ax
-        add si, 2
-        inc ax
-
-        pop bx
-        cmp ax, bx
-        jb short cache_sums_loop
-        ret
-
-; Prints the characters of a buffer referenced by si
-print_buffer:
-        mov bh, si[1]
-
-        add si, 2
-        mov ch, 0
-
-        mov ah, 2h
-print_buffer_loop:
-        mov dl, [si]
-        int 21h
-
-        inc ch
-        inc si
-
-        cmp ch, bh
-        jb short print_buffer_loop
-        ret
-
-; Iterate a from 0 to max
-iter:
-        mov ax, a
-        call test_num
-
-        inc ax
-        mov a, ax
-        cmp ax, max
-        jbe short iter
-
-        call proved
-
-; Iterate b from a to max
-test_num:
-        mov ax, a
-        mov b, ax
-
-test_loop:
-        call test_pair
-
-        inc b
-        mov ax, b
-        cmp ax, max
-        jbe short test_loop
-        ret        
-
-test_pair:
-        ; Calculate S(A + B) and store it in sumAB
-        mov si, offset sums_cache
-        add si, a
-        add si, b
-        mov ax, [si]
-        mov sumAB, ax
-        mov ax, si
-
-        ; Calculate S(A) and store it in sumA
-        mov si, offset sums_cache
-        add si, a
-        mov ax, [si]
-        mov sumA, ax
-
-        ; Calculate S(B) and store it in sumB
-        mov si, offset sums_cache
-        add si, b
-        mov ax, [si]
-        mov sumB, ax 
-
-
-        ; Calculate S(a + b) - S(a) - S(b) in ax
-        mov ax, sumAB
-        sub ax, sumA
-        sub ax, sumB
-
-        mov cx, 9 ; Set the devident to 9
-        mov dx, 0 ; Clear the register where the rest will be stored
-        div cx
-
-        cmp dx, 0
-        jne disproved
-
-        ret
-
-sum_digits:
-        mov cx, 10 ; Store the devident in cx
-        mov bx, 0 ; Clear the register where the result will be stored
-sum_loop:
-        mov dx, 0 ; Clear the rest of the division
-
-        div cx ; Divide ax by cx
-        add bx, dx ; Add the rest of the division ax/cx to bx
-
-        ; Loop until ax equals 0
-        cmp ax, 0
-        ja short sum_loop
-        ret
-
-proved:
-        call print_time
-
-        mov ah, 9h
-        mov dx, offset proof
-        int 21h
-
-        mov ax, max
-        call print_uint
-
-        ; Print '!\n'
-        mov ah, 2h
-        mov dx, '!'
-        int 21h
-        mov dx, 0ah
-        int 21h
-
-        call quit
-        ret
-
-disproved:
-        mov ah, 9h
-        mov dx, offset counter
-        int 21h
-
-        mov ax, a
-        call print_uint
-
-        ; Print ', '
-        mov ah, 2h
-        mov dx, ','
-        int 21h
-        mov dx, ' '
-        int 21h
-
-        mov ax, b
-        call print_uint
-
-        ; Print ')\n'
-        mov ah, 2h
-        mov dx, ')'
-        int 21h
-        mov dx, 0ah
-        int 21h
-
-        call quit
-        ret
-
-print_uint:
-        mov bx, 10
-        mov cx, 0
-
-print_uint_collect:
-        mov dx, 0
-        div bx
-        add dx, 30h
-
-        push dx
-        inc cx
-
-        cmp ax, 0
-        ja short print_uint_collect
-
-        mov ah, 2h
-
-print_uint_loop:
-        pop dx
-        int 21h
-        dec cx
-
-        cmp cx, 0
-        ja short print_uint_loop
-        ret
-
-print_time:
-        ; Set the end_time variable
-        mov si, offset end_time
-        call get_time
-
-        mov ah, 9h
-        mov dx, offset loaded
-        int 21h
-
-        ; Print the elepsed time in milliseconds
-        mov ax, end_time
-        sub ax, start_time
-        mov cx, 10
-        mul cx
-        call print_uint
-
-        ; Print 'ms\n'
-        mov ah, 2h
-        mov dx, 'm'
-        int 21h
-        mov dx, 's'
-        int 21h
-        mov dx, 0ah
-        int 21h
-        ret
-
-; Gets the current minute in centiseconds and stores it in [si]
-get_time:
-        ; Get system time
-        mov ah, 2ch
-        int 21h
-
-        ; Add the minutes
-        mov ax, 0
-        mov al, ch
-        mov bx, 6000
-        mul bx
-        mov [si], ax
-
-        ; Add the seconds
-        mov ax, 0
-        mov al, dh
-        mov bx, 100
-        mul bx
-        add [si], ax
-
-        ; Add the centiseconds
-        mov ax, 0
-        mov al, dl
-        add [si], ax
-
-        ret
-
-; Print decimal value in ax, and a '.' to separate them. This was created for debugging porposes.
-print_dot_dec:
-        push bx
-        push cx
-        push dx
-        push ax
-        call print_uint
-        mov dx, '.'
-        int 21h
-        pop ax    
-        pop dx
-        pop cx
-        pop bx
-        ret
-        
-quit:
-        mov ax, 4c00h
-        int 21h
-end start