- Commit
- d1ec6e64e95a15e0bccb7374ddd759f070d4619f
- Parent
- c64b0a508beb5e2010927c141593415840358da8
- Author
- Pablo Escobar Gaviria <gark.garcia@protonmail.com>
- Date
Restructured the repo.
Also cleaned the C implementation.
An exercise on polyglossy: the same problem solved on multiple languages
Restructured the repo.
Also cleaned the C implementation.
31 files changed, 1546 insertions, 1512 deletions
Status | File Name | N° Changes | Insertions | Deletions |
Modified | .gitignore | 20 | 11 | 9 |
Modified | C++/main.cpp | 164 | 82 | 82 |
Modified | C/main.c | 282 | 141 | 141 |
Added | Elixir/conjecture/.formatter.exs | 4 | 4 | 0 |
Added | Elixir/conjecture/.gitignore | 24 | 24 | 0 |
Added | Elixir/conjecture/lib/conjecture.ex | 73 | 73 | 0 |
Added | Elixir/conjecture/mix.exs | 28 | 28 | 0 |
Added | Elixir/conjecture/test/conjecture_test.exs | 8 | 8 | 0 |
Added | Elixir/conjecture/test/test_helper.exs | 1 | 1 | 0 |
Modified | Go/conjecture.go | 240 | 120 | 120 |
Deleted | Haskell/.gitignore | 5 | 0 | 5 |
Added | Haskell/Main.hs | 76 | 76 | 0 |
Deleted | Haskell/app/Main.hs | 77 | 0 | 77 |
Deleted | Haskell/package.yaml | 34 | 0 | 34 |
Deleted | Haskell/stack.yaml | 68 | 0 | 68 |
Modified | Java/.gitignore | 8 | 4 | 4 |
Modified | Java/src/conjecture/Main.java | 126 | 63 | 63 |
Modified | Kotlin/.gitignore | 2 | 1 | 1 |
Modified | Kotlin/Kotli.iml | 22 | 11 | 11 |
Modified | Kotlin/src/main.kt | 112 | 56 | 56 |
Modified | README.md | 58 | 30 | 28 |
Modified | Rust/.gitignore | 4 | 2 | 2 |
Modified | Rust/Cargo.lock | 2 | 2 | 0 |
Modified | Rust/Cargo.toml | 12 | 6 | 6 |
Modified | Rust/src/main.rs | 237 | 118 | 119 |
Modified | hla/conjecture.hla | 258 | 129 | 129 |
Modified | script.js | 79 | 39 | 40 |
Modified | script.pl | 56 | 28 | 28 |
Modified | script.py | 68 | 34 | 34 |
Modified | script.rb | 84 | 42 | 42 |
Modified | x86/PROGRAM.ASM | 826 | 413 | 413 |
diff --git a/.gitignore b/.gitignore @@ -1,9 +1,11 @@ -.idea -.vscode -*.exe -*.img -*.IMG -Executables -Statistics -Latex -Q# +.idea +.vscode +*.exe +*.img +*.IMG +bin +bin/ +build +Statistics +Latex +Q#
diff --git a/C++/main.cpp b/C++/main.cpp @@ -1,83 +1,83 @@ -#include <chrono> -#include <iostream> -#include <string> -#include <thread> -#include <map> -#include <vector> -#include <charconv> - -#define SUCCESS 0 -#define FAIL 1 -#define INVALID_INPUT 2 - -std::map<unsigned int, unsigned int> sums_cache; - -inline unsigned int sum_digits(unsigned int n) -{ - unsigned int sum = 0; - while (n != 0) - { - sum += (n % 10); - n /= 10; - } - - return sum; -} - -void get_counterexpl_thread(unsigned int start, unsigned int max, unsigned int interval) -{ - for (auto a = start; a <= max; a += interval) - for (auto b = a; b <= max; b++) - { - auto diff = sums_cache[a + b] - (sums_cache[a] + sums_cache[b]); - - if (diff % 9 != 0) - exit(FAIL); - } -} - -bool read_first_arg(int argc, char *argv[], unsigned int *value) -{ - if (argc > 1) - { - std::string value_str = argv[1]; - - try - { - *value = std::stoul(value_str); - return true; - } - catch (...) - { - return false; - } - } - else return false; -} - -int main(int argc, char *argv[]) -{ - unsigned int max; - if (read_first_arg(argc, argv, &max)) - { - auto n_threads = std::thread::hardware_concurrency(); - std::vector<std::thread> threads; - - // Builds the sums cache - for (int i = 0; i != 2 * max; i++) - sums_cache[i] = sum_digits(i); - - // Distributes calculations across threads evenlly - for (int i = 0; i < n_threads; i++) - { - auto thread = std::thread(get_counterexpl_thread, i, max, n_threads); - thread.join(); - } - - return SUCCESS; - } - else - { - return INVALID_INPUT; - } +#include <chrono> +#include <iostream> +#include <string> +#include <thread> +#include <map> +#include <vector> +#include <charconv> + +#define SUCCESS 0 +#define FAIL 1 +#define INVALID_INPUT 2 + +std::map<unsigned int, unsigned int> sums_cache; + +inline unsigned int sum_digits(unsigned int n) +{ + unsigned int sum = 0; + while (n != 0) + { + sum += (n % 10); + n /= 10; + } + + return sum; +} + +void get_counterexpl_thread(unsigned int start, unsigned int max, unsigned int interval) +{ + for (auto a = start; a <= max; a += interval) + for (auto b = a; b <= max; b++) + { + auto diff = sums_cache[a + b] - (sums_cache[a] + sums_cache[b]); + + if (diff % 9 != 0) + exit(FAIL); + } +} + +bool read_first_arg(int argc, char *argv[], unsigned int *value) +{ + if (argc > 1) + { + std::string value_str = argv[1]; + + try + { + *value = std::stoul(value_str); + return true; + } + catch (...) + { + return false; + } + } + else return false; +} + +int main(int argc, char *argv[]) +{ + unsigned int max; + if (read_first_arg(argc, argv, &max)) + { + auto n_threads = std::thread::hardware_concurrency(); + std::vector<std::thread> threads; + + // Builds the sums cache + for (int i = 0; i != 2 * max; i++) + sums_cache[i] = sum_digits(i); + + // Distributes calculations across threads evenlly + for (int i = 0; i < n_threads; i++) + { + auto thread = std::thread(get_counterexpl_thread, i, max, n_threads); + thread.join(); + } + + return SUCCESS; + } + else + { + return INVALID_INPUT; + } } \ No newline at end of file
diff --git a/C/main.c b/C/main.c @@ -1,141 +1,141 @@ -#include <stdlib.h> -#include <stdio.h> -#include <pthread.h> - -// Imports to get system information -#ifdef _WIN32 -#include <windows.h> -#elif MACOS -#include <sys/param.h> -#include <sys/sysctl.h> -#else -#include <unistd.h> -#endif - -#define SUCCESS 0 -#define FAIL 1 -#define INVALID_INPUT 2 - -// This 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. - -int err = SUCCESS; // Global error condition -int *sums_cache; // Shared memory between threads - -// Memory structure to pass arguments to threads using the pthreads library -struct iter_info -{ - int start; - int interval; - int max; -}; - -// Find the number of processors on host machine -int get_num_cores() -{ -#ifdef WIN32 - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - return sysinfo.dwNumberOfProcessors; -#elif MACOS - int nm[2]; - size_t len = 4; - uint32_t count; - - nm[0] = CTL_HW; - nm[1] = HW_AVAILCPU; - sysctl(nm, 2, &count, &len, NULL, 0); - - if (count < 1) - { - nm[1] = HW_NCPU; - sysctl(nm, 2, &count, &len, NULL, 0); - if (count < 1) - { - count = 1; - } - } - return count; -#else - return sysconf(_SC_NPROCESSORS_ONLN); -#endif -} - -int sum_digits(unsigned n) -{ - int parc = n; - int sum = 0; - - while (parc > 0) - { - sum += parc % 10; - parc /= 10; - } - return sum; -} - -int get_counterexpl_iter(struct iter_info *iter) -{ - for (int a = iter->start; a <= iter->max; a += iter->interval) - for (int b = a; b <= iter->max; b++) - { - if ((sums_cache[a + b] - (sums_cache[a] + sums_cache[b])) % 9 != 0) - { - err = 1; - return FAIL; - } - } - - return SUCCESS; -} - -int main(int argc, char *argv[]) -{ - if (argc > 1) { - - // Get the length of argv[1] - int len; - for (len = 0; argv[len] != '\0'; len++); - - // Check if argv[1] is numeric - for (int i = 0; i < len; i++) - if (argv[1][i] < '0' || argv[1][i] > '9') - return INVALID_INPUT; - - unsigned int max = strtoul(argv[1], NULL, 10); - int n_threads = get_num_cores(); - pthread_t thread_ids[n_threads]; - struct iter_info thread_iters[n_threads]; - - // Create the sums cache - int sums_c = 2 * max; - sums_cache = malloc(sizeof(int) * sums_c * 2); //original (sizeof(int)* sums_c) causing seg faults in multi-threading - for (int i = 0; i <= sums_c; i++) - sums_cache[i] = sum_digits(i); - - - // Create the threads, divide the task into number of threads equivalent to number - // of cores on the host machine - for (int i = 0; i < n_threads; i++) - { - thread_iters[i].start = i; - thread_iters[i].max = max; - thread_iters[i].interval = n_threads; - err = pthread_create(&thread_ids[i], NULL, get_counterexpl_iter, &thread_iters[i]); - - if (err) printf("Unable to create thread : %d\n", err); - } - - for (int i = 0; i < n_threads; i++) - { - err = pthread_join(thread_ids[i], NULL); - if (err) printf("Unable to join threads : %d\n", err); - } - - return err; - } else { - return INVALID_INPUT; - } -} +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> + +// Imports to get system information +#ifdef _WIN32 +#include <windows.h> +#elif MACOS +#include <sys/param.h> +#include <sys/sysctl.h> +#else +#include <unistd.h> +#endif + +#define SUCCESS 0 +#define FAIL 1 +#define INVALID_INPUT 2 + +// This 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. + +int err = SUCCESS; // Global error condition +int *sums_cache; // Shared memory between threads + +// Memory structure to pass arguments to threads using the pthreads library +struct iter_info +{ + int start; + int interval; + int max; +}; + +// Find the number of processors on host machine +int get_num_cores() +{ +#ifdef WIN32 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#elif MACOS + int nm[2]; + size_t len = 4; + uint32_t count; + + nm[0] = CTL_HW; + nm[1] = HW_AVAILCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + + if (count < 1) + { + nm[1] = HW_NCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + if (count < 1) + { + count = 1; + } + } + return count; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +int sum_digits(unsigned n) +{ + int parc = n; + int sum = 0; + + while (parc > 0) + { + sum += parc % 10; + parc /= 10; + } + return sum; +} + +int get_counterexpl_iter(struct iter_info *iter) +{ + for (int a = iter->start; a <= iter->max; a += iter->interval) + for (int b = a; b <= iter->max; b++) + { + if ((sums_cache[a + b] - (sums_cache[a] + sums_cache[b])) % 9 != 0) + { + err = 1; + return FAIL; + } + } + + return SUCCESS; +} + +int main(int argc, char *argv[]) +{ + if (argc > 1) + { + // Check if argv[1] is numeric + int i = 0; + while (argv[1][i] != '\0') + { + if (argv[1][i] < '0' || argv[1][i] > '9') + return INVALID_INPUT; + + i++; + } + + unsigned int max = strtoul(argv[1], NULL, 10); + int n_threads = get_num_cores(); + pthread_t thread_ids[n_threads]; + struct iter_info thread_iters[n_threads]; + + // Create the sums cache + int sums_c = 2 * max; + sums_cache = malloc(sizeof(int) * sums_c * 2); //original (sizeof(int)* sums_c) causing seg faults in multi-threading + for (int i = 0; i <= sums_c; i++) + sums_cache[i] = sum_digits(i); + + + // Create the threads, divide the task into number of threads equivalent to number + // of cores on the host machine + for (int i = 0; i < n_threads; i++) + { + thread_iters[i].start = i; + thread_iters[i].max = max; + thread_iters[i].interval = n_threads; + err = pthread_create(&thread_ids[i], NULL, get_counterexpl_iter, &thread_iters[i]); + + if (err) fprintf(stderr, "Unable to create thread : %d\n", err); + } + + for (int i = 0; i < n_threads; i++) + { + err = pthread_join(thread_ids[i], NULL); + if (err) fprintf(stderr, "Unable to join threads : %d\n", err); + } + + return err; + } + else return INVALID_INPUT; +}
diff --git a/Elixir/conjecture/.formatter.exs b/Elixir/conjecture/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +]
diff --git a/Elixir/conjecture/.gitignore b/Elixir/conjecture/.gitignore @@ -0,0 +1,24 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +conjecture-*.tar +
diff --git a/Elixir/conjecture/lib/conjecture.ex b/Elixir/conjecture/lib/conjecture.ex @@ -0,0 +1,73 @@ +defmodule Conjecture do + INVALID_INPUT = 2 + + def main do + case System.argv() |> Enum.map(fn s -> Integer.parse s end) do + [{max, ""}, {n_processes, ""}] -> run max, n_processes + _ -> System.halt INVALID_INPUT + end + end + + def run max, n_processes do + if max < 0 or n_processes <= 0 do + System.halt INVALID_INPUT + else + # Spawn a new process for each starting index from 0 to ``max` + f = fn i -> spawn fn -> counterexpl i, max, n_processes end end + pids = Enum.map 0..max, f + + # Send the current PID to each process + Enum.map pids, fn pid -> send pid, self() end + listen + end + end + + # Listen for messages on all processes + def listen do + receive do + :found -> System.halt 1 + :ok -> listen + end + end + + def counterexpl start, max, n_processes do + receive do + parent_pid -> + if counterexpl_loop start, max, n_processes do + send parent_pid, :found + else + send parent_pid, :ok + end + end + end + + def counterexpl_loop a, max, n_processes do + cond do + iter a, 0 -> true + a + n_processes <= max -> + counterexpl_loop (a + n_processes), max, n_processes + true -> false + end + end + + def iter a, b do + cond do + test a, b -> true + b + 1 < a -> iter a, b + 1 + true -> false + end + end + + def test a, b do + rem (sum (a + b) - sum a - sum b), 9 == 0 + end + + def sum 0 do 0 end + + def sum n do + d = rem n, 10 + r = div n, 10 + + d + sum r + end +end
diff --git a/Elixir/conjecture/mix.exs b/Elixir/conjecture/mix.exs @@ -0,0 +1,28 @@ +defmodule Conjecture.MixProject do + use Mix.Project + + def project do + [ + app: :conjecture, + version: "0.1.0", + elixir: "~> 1.9", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + # {:dep_from_hexpm, "~> 0.3.0"}, + # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} + ] + end +end
diff --git a/Elixir/conjecture/test/conjecture_test.exs b/Elixir/conjecture/test/conjecture_test.exs @@ -0,0 +1,8 @@ +defmodule ConjectureTest do + use ExUnit.Case + doctest Conjecture + + test "greets the world" do + assert Conjecture.hello() == :world + end +end
diff --git a/Elixir/conjecture/test/test_helper.exs b/Elixir/conjecture/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start()
diff --git a/Go/conjecture.go b/Go/conjecture.go @@ -1,120 +1,120 @@ -package main - -// This 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 interger. - -import ( - "os" - "strconv" -) - -type iter struct { - Start uint - Max uint - Interval uint -} - -const success = 0 -const fail = 1 -const invalidInput = 2 - -func main() { - if len(os.Args) > 0 { - nThreads := uint(1) - - if len(os.Args) > 1 { - if arg, err := strconv.ParseUint(os.Args[2], 10, 64); err == nil && arg >= 1 { - nThreads = uint(arg) - } - } - - if max, err := strconv.ParseUint(os.Args[0], 10, 64); err == nil { - if getCounterexample(uint(max), nThreads) { - os.Exit(fail) - } else { - os.Exit(success) - } - } else { - os.Exit(invalidInput) - } - } else { - os.Exit(invalidInput) - } - -} - -func getCounterexample(max uint, nThreads uint) bool { - sums := getSums(max) - - if nThreads > 1 { - channels := make([](chan bool), nThreads) - - // Compute the result of each sub-range - for i := 0; i < int(nThreads); i++ { - channels[i] = make(chan bool) - it := iter{uint(i), max, nThreads} - - go getCounterIter(it, &sums, channels[i]) - } - - // Listen for the computation to finish - for _, c := range channels { - if msg := <-c; msg { - return true - } - } - } else { - c := make(chan bool) - it := iter{0, max, 1} - - go getCounterIter(it, &sums, c) - - return <-c - } - - return false -} - -func getCounterIter(it iter, sums *[]int, c chan bool) { - for a := it.Start; a <= it.Max; a += it.Interval { - for b := a; b <= it.Max; b++ { - diff := (*sums)[a+b] - (*sums)[a] - (*sums)[b] - - if diff%9 != 0 { - c <- true - close(c) - - return - } - } - } - - c <- false - close(c) -} - -func getSums(max uint) []int { - maxRange := 2*max + 1 - sums := make([]int, maxRange) - - for i := range sums { - sums[i] = sumDigits(uint(i)) - } - - return sums -} - -func sumDigits(n uint) int { - var sum uint - - for { - if n <= 0 { - return int(sum) - } - - sum += n % 10 - n /= 10 - } -} +package main + +// This 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 interger. + +import ( + "os" + "strconv" +) + +type iter struct { + Start uint + Max uint + Interval uint +} + +const success = 0 +const fail = 1 +const invalidInput = 2 + +func main() { + if len(os.Args) > 0 { + nThreads := uint(1) + + if len(os.Args) > 1 { + if arg, err := strconv.ParseUint(os.Args[2], 10, 64); err == nil && arg >= 1 { + nThreads = uint(arg) + } + } + + if max, err := strconv.ParseUint(os.Args[0], 10, 64); err == nil { + if getCounterexample(uint(max), nThreads) { + os.Exit(fail) + } else { + os.Exit(success) + } + } else { + os.Exit(invalidInput) + } + } else { + os.Exit(invalidInput) + } + +} + +func getCounterexample(max uint, nThreads uint) bool { + sums := getSums(max) + + if nThreads > 1 { + channels := make([](chan bool), nThreads) + + // Compute the result of each sub-range + for i := 0; i < int(nThreads); i++ { + channels[i] = make(chan bool) + it := iter{uint(i), max, nThreads} + + go getCounterIter(it, &sums, channels[i]) + } + + // Listen for the computation to finish + for _, c := range channels { + if msg := <-c; msg { + return true + } + } + } else { + c := make(chan bool) + it := iter{0, max, 1} + + go getCounterIter(it, &sums, c) + + return <-c + } + + return false +} + +func getCounterIter(it iter, sums *[]int, c chan bool) { + for a := it.Start; a <= it.Max; a += it.Interval { + for b := a; b <= it.Max; b++ { + diff := (*sums)[a+b] - (*sums)[a] - (*sums)[b] + + if diff%9 != 0 { + c <- true + close(c) + + return + } + } + } + + c <- false + close(c) +} + +func getSums(max uint) []int { + maxRange := 2*max + 1 + sums := make([]int, maxRange) + + for i := range sums { + sums[i] = sumDigits(uint(i)) + } + + return sums +} + +func sumDigits(n uint) int { + var sum uint + + for { + if n <= 0 { + return int(sum) + } + + sum += n % 10 + n /= 10 + } +}
diff --git a/Haskell/.gitignore b/Haskell/.gitignore @@ -1,4 +0,0 @@ -.stack-work -.idea -*.cabal -stack.yaml- \ No newline at end of file
diff --git a/Haskell/Main.hs b/Haskell/Main.hs @@ -0,0 +1,76 @@ +-- 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. + +module Main where + +import Numeric (readDec) +import Numeric.Natural +import System.Environment +import System.Exit +import Control.Monad (foldM) +import Data.Map (Map, insert, empty) +import qualified Data.Map + +main :: IO Int +main = do + args <- getArgs + + case head' args >>= Just . readDec of + Just [(max, "")] -> + if counter' max then exitFailure else exitSuccess + _ -> exitInvalidInput + + where head' [] = Nothing + head' xs = Just (head xs) + +-- Calculates the sum of the digits of `n`. +sum' :: Natural -> Int +sum' n + | n < 10 = fromEnum n + | otherwise = fromEnum (n `mod` 10) + sum' (n `div` 10) + +-- Returns `Just updated` if the if the conjecture holds for pair, where +-- `updated` is an updated versions of the sums cache provided by `sums`. +-- Otherwise returns `Nothing`. +test' :: Map Natural Int -> (Natural, Natural) -> Maybe (Map Natural Int) +test' sums pair = + case diff sums pair of + Left updated -> + test' updated pair + + Right dif -> + if dif `mod` 9 == 0 then Just sums else Nothing + +-- Given a cache of the image of `sum'`, attemps to lookup `sum' a`, `sum' b` +-- and `sum' $ a + b`. +-- If the lookup succeeds, returns `Right (sum' (a + b) - sum' a - sum' a)`. +-- Otherwise inserts the value that caused the failure to `sums` and returns +-- `Left sums`. +diff :: Map Natural Int -> (Natural, Natural) -> Either (Map Natural Int) Int +diff sums (a, b) = do + sa <- lookupOrInsert a + sb <- lookupOrInsert b + sab <- lookupOrInsert $ a + b + + pure $ sab - sa - sb + where lookupOrInsert x = + case Data.Map.lookup x sums of + Just sx -> Right sx + + Nothing -> Left (insert x (sum' x) sums) + +-- Checks if there is any counterexample in +-- [(a, b) | a <- [0..max], b <- [a..max]]. +-- +-- Returns `True` if a counter example was found. +-- Otherwise returns `False`. +counter' :: Natural -> Bool +counter' max = + case foldM test' empty [(a, b) | a <- [0..max], b <- [a..max]] of + Nothing -> True + Just _ -> False + +exitInvalidInput :: IO Int +exitInvalidInput = exitWith $ ExitFailure 2
diff --git a/Haskell/app/Main.hs b/Haskell/app/Main.hs @@ -1,76 +0,0 @@ --- 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. - -module Main where - -import Numeric (readDec) -import Numeric.Natural -import System.Environment -import System.Exit -import Control.Monad (foldM) -import Data.Map (Map, insert, empty) -import qualified Data.Map - -main :: IO Int -main = do - args <- getArgs - - case head' args >>= Just . readDec of - Just [(max, "")] -> - if counter' max then exitFailure else exitSuccess - _ -> exitInvalidInput - - where head' [] = Nothing - head' xs = Just (head xs) - --- Calculates the sum of the digits of `n`. -sum' :: Natural -> Int -sum' n - | n < 10 = fromEnum n - | otherwise = fromEnum (n `mod` 10) + sum' (n `div` 10) - --- Returns `Just updated` if the if the conjecture holds for pair, where --- `updated` is an updated versions of the sums cache provided by `sums`. --- Otherwise returns `Nothing`. -test' :: Map Natural Int -> (Natural, Natural) -> Maybe (Map Natural Int) -test' sums pair = - case diff sums pair of - Left updated -> - test' updated pair - - Right dif -> - if dif `mod` 9 == 0 then Just sums else Nothing - --- Given a cache of the image of `sum'`, attemps to lookup `sum' a`, `sum' b` --- and `sum' $ a + b`. --- If the lookup succeeds, returns `Right (sum' (a + b) - sum' a - sum' a)`. --- Otherwise inserts the value that caused the failure to `sums` and returns --- `Left sums`. -diff :: Map Natural Int -> (Natural, Natural) -> Either (Map Natural Int) Int -diff sums (a, b) = do - sa <- lookupOrInsert a - sb <- lookupOrInsert b - sab <- lookupOrInsert $ a + b - - pure $ sab - sa - sb - where lookupOrInsert x = - case Data.Map.lookup x sums of - Just sx -> Right sx - - Nothing -> Left (insert x (sum' x) sums) - --- Checks if there is any counterexample in --- [(a, b) | a <- [0..max], b <- [a..max]]. --- --- Returns `True` if a counter example was found. --- Otherwise returns `False`. -counter' :: Natural -> Bool -counter' max = - case foldM test' empty [(a, b) | a <- [0..max], b <- [a..max]] of - Nothing -> True - Just _ -> False - -exitInvalidInput :: IO Int -exitInvalidInput = exitWith $ ExitFailure 2- \ No newline at end of file
diff --git a/Haskell/package.yaml b/Haskell/package.yaml @@ -1,33 +0,0 @@ -name: conjecture -version: 1.0.0.0 -license: MIT -author: "GarkGarcia" -maintainer: "gark.garcia@protonmail.com" -copyright: "2019 GarkGarcia" - -extra-source-files: [] - -# Metadata used when publishing your package -# synopsis: Short description of your package -# category: Web - -# To avoid duplicated efforts in documentation and dealing with the -# complications of embedding Haddock markup inside cabal files, it is -# common to point users to the README.md file. -description: This program is a simple test for a little conjecture of mine. - -dependencies: - - base >= 4.7 && < 5 - - containers == 0.6.2.1 - -executables: - haskell: - main: Main.hs - source-dirs: app - ghc-options: - - -threaded - - -rtsopts - - -with-rtsopts=-N - - -O - dependencies: - - containers == 0.6.2.1- \ No newline at end of file
diff --git a/Haskell/stack.yaml b/Haskell/stack.yaml @@ -1,68 +0,0 @@ -# This file was automatically generated by 'stack init' -# -# Some commonly used options have been documented as comments in this file. -# For advanced use and comprehensive documentation of the format, please see: -# https://docs.haskellstack.org/en/stable/yaml_configuration/ - -# Resolver to choose a 'specific' stackage snapshot or a compiler version. -# A snapshot resolver dictates the compiler version and the set of packages -# to be used for project dependencies. For example: -# -# resolver: lts-3.5 -# resolver: nightly-2015-09-21 -# resolver: ghc-7.10.2 -# -# The location of a snapshot can be provided as a file or url. Stack assumes -# a snapshot provided as a file might change, whereas a url resource does not. -# -# resolver: ./custom-snapshot.yaml -# resolver: https://example.com/snapshots/2018-01-01.yaml -resolver: lts-13.10 - -# User packages to be built. -# Various formats can be used as shown in the example below. -# -# packages: -# - some-directory -# - https://example.com/foo/bar/baz-0.0.2.tar.gz -# - location: -# git: https://github.com/commercialhaskell/stack.git -# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# subdirs: -# - auto-update -# - wai -packages: - - . -# Dependency packages to be pulled from upstream that are not in the resolver -# using the same syntax as the packages field. -# (e.g., acme-missiles-0.3) -extra-deps: [] -# - conduit-1.2.13.1@sha256:afd4db7fe66ae7af3d418e1a932384a8dee08df2f6299cca80e53ba964ce1228 -# - conduit-extra-1.1.17@sha256:a4e6f476ba86db2c7cb76993b43b2a156b010de2917d239af66f9d7e7599e269 -# - resourcet-1.1.11@sha256:096a3db6774a728bbe264e3e25c4e40d60e527ebd4b90c0b311deaa8d4cf4f27 -# - streaming-commons-0.1.19@sha256:3a02f84578f75eac1425dca877f8d697b68d379a21970c1dad96196620404803 - -# Override default flag values for local packages and extra-deps -# flags: {} - -# Extra package databases containing global packages -# extra-package-dbs: [] - -# Control whether we use the GHC we find on the path -# system-ghc: true -# -# Require a specific version of stack, using version ranges -# require-stack-version: -any # Default -# require-stack-version: ">=1.9" -# -# Override the architecture used by stack, especially useful on Windows -# arch: i386 -# arch: x86_64 -# -# Extra directories used by stack for building -# extra-include-dirs: [/path/to/dir] -# extra-lib-dirs: [/path/to/dir] -# -# Allow a newer minor version of GHC than the snapshot specifies -# compiler-check: newer-minor
diff --git a/Java/.gitignore b/Java/.gitignore @@ -1,4 +1,4 @@ -.idea -out -src/META-INF -Java.iml +.idea +out +src/META-INF +Java.iml
diff --git a/Java/src/conjecture/Main.java b/Java/src/conjecture/Main.java @@ -1,64 +1,64 @@ -package conjecture; - -// 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. - -import java.util.InputMismatchException; - -public class Main { - private static final int SUCCESS = 0; - private static final int FAIL = 1; - private static final int INVALID_INPUT = 2; - - public static void main(String[] args) { - try { - int max = Integer.parseInt(args[0]); - - if (getCounterexample(max)) { - System.exit(FAIL); - } else { - System.exit(SUCCESS); - } - } catch (InputMismatchException error) { - System.exit(INVALID_INPUT); - } - - } - - private static Boolean getCounterexample(int max) { - int[] sum = getSums(max); - - for (int a = 0; a <= max; a++) - for (int b = a; b <= max; b++) { - int diff = sum[a + b] - (sum[a] + sum[b]); - - if (diff % 9 != 0) - return true; - } - - return false; - } - - private static int[] getSums(int max) { - int maxRange = 2 * (max + 1); - int[] sums = new int[maxRange]; - - for (int i = 0; i < maxRange; i++) - sums[i] = sumDigits(i); - - return sums; - } - - private static int sumDigits(int n) { - int num = Math.abs(n), sum = 0; - - while (num > 0) { - sum += num % 10; - num /= 10; - } - - return sum; - } +package conjecture; + +// 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. + +import java.util.InputMismatchException; + +public class Main { + private static final int SUCCESS = 0; + private static final int FAIL = 1; + private static final int INVALID_INPUT = 2; + + public static void main(String[] args) { + try { + int max = Integer.parseInt(args[0]); + + if (getCounterexample(max)) { + System.exit(FAIL); + } else { + System.exit(SUCCESS); + } + } catch (InputMismatchException error) { + System.exit(INVALID_INPUT); + } + + } + + private static Boolean getCounterexample(int max) { + int[] sum = getSums(max); + + for (int a = 0; a <= max; a++) + for (int b = a; b <= max; b++) { + int diff = sum[a + b] - (sum[a] + sum[b]); + + if (diff % 9 != 0) + return true; + } + + return false; + } + + private static int[] getSums(int max) { + int maxRange = 2 * (max + 1); + int[] sums = new int[maxRange]; + + for (int i = 0; i < maxRange; i++) + sums[i] = sumDigits(i); + + return sums; + } + + private static int sumDigits(int n) { + int num = Math.abs(n), sum = 0; + + while (num > 0) { + sum += num % 10; + num /= 10; + } + + return sum; + } } \ No newline at end of file
diff --git a/Kotlin/.gitignore b/Kotlin/.gitignore @@ -1,2 +1,2 @@ -.idea +.idea out \ No newline at end of file
diff --git a/Kotlin/Kotli.iml b/Kotlin/Kotli.iml @@ -1,12 +1,12 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="library" name="KotlinJavaRuntime" level="project" /> - </component> +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="library" name="KotlinJavaRuntime" level="project" /> + </component> </module> \ No newline at end of file
diff --git a/Kotlin/src/main.kt b/Kotlin/src/main.kt @@ -1,57 +1,57 @@ -package conjecture - -import kotlin.math.absoluteValue -import kotlin.system.exitProcess - -// 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. - -fun main(args: Array<String>) { - try { - val max = args[0].toInt() - - if (counterexample(max)) exitProcess(1) - else exitProcess(0) - - } catch (_: Exception) { - exitProcess(2) - } -} - -internal fun counterexample(max: Int): Boolean { - val sum = sums(max) - - for (a in 0..max) - for (b in a..max) { - val diff = sum[a + b] - sum[a] - sum[b] - - if (diff % 9 != 0) - return true - } - - return false -} - -fun sums (max: Int): IntArray { - val maxRange = 2 * max + 1 - val sums = IntArray(maxRange) - - for (i in 0 until maxRange) - sums[i] = sumDigits(i) - - return sums -} - -fun sumDigits(n: Int): Int { - var sum = 0 - var num = n.absoluteValue - - while (num > 0) { - sum += num % 10 - num /= 10 - } - - return sum +package conjecture + +import kotlin.math.absoluteValue +import kotlin.system.exitProcess + +// 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. + +fun main(args: Array<String>) { + try { + val max = args[0].toInt() + + if (counterexample(max)) exitProcess(1) + else exitProcess(0) + + } catch (_: Exception) { + exitProcess(2) + } +} + +internal fun counterexample(max: Int): Boolean { + val sum = sums(max) + + for (a in 0..max) + for (b in a..max) { + val diff = sum[a + b] - sum[a] - sum[b] + + if (diff % 9 != 0) + return true + } + + return false +} + +fun sums (max: Int): IntArray { + val maxRange = 2 * max + 1 + val sums = IntArray(maxRange) + + for (i in 0 until maxRange) + sums[i] = sumDigits(i) + + return sums +} + +fun sumDigits(n: Int): Int { + var sum = 0 + var num = n.absoluteValue + + while (num > 0) { + sum += num % 10 + num /= 10 + } + + return sum } \ No newline at end of file
diff --git a/README.md b/README.md @@ -1,28 +1,30 @@ -# A Conjecture of Mine -An exercise on _polyglossy_. The same problem solved on multiple languages. - -## The Problem - Mathematicians Version -Let <img src="https://latex.codecogs.com/svg.latex?S:&space;\mathbb{N}\rightarrow&space;\mathbb{N}"/> be the sum of the digits of a positive integer in a [_base 10 positional number system_](https://en.wikipedia.org/wiki/Positional_notation). We have: - -<img src="https://latex.codecogs.com/svg.latex?\forall&space;a,&space;b&space;\in&space;\mathbb{N},&space;S_{a&space;+&space;b}&space;\equiv&space;S_a&space;+&space;S_b&space;\;\(\textup{mod}\;&space;9&space;\)"/> - -### Addendum -This conjecture can be generalized for any _positional number system_. Check out `proof.pdf` for more information. - -## The Problem - Programmers Verison - -Let `S(n: uint) -> uint` be the sum of the digits of `n` in [_base 10_](https://en.wikipedia.org/wiki/Decimal). Then, for all `a` and `b` of type `uint`, `S(a + b) - ( S(a) + S(b) ) % 9 == 0`. - -## Performance -The conjecture was [proved by exhaustion](https://en.wikipedia.org/wiki/Proof_by_exhaustion) for the interval <img src="https://latex.codecogs.com/svg.latex?[0,&space;10^4]"/> in multiple language implementations. The performance of each language was then avaliated as the following: - -|Language |Milliseconds| -|--------------|------------| -|**Rust** |103 | -|**C** |113 | -|**Kotlin** |137 | -|**Go** |155 | -|**JavaScript**|656 | -|**Ruby** |9850 | -|**Python** |16032 | -|**Haskell** |28365 | +# A Conjecture of Mine +An exercise on _polyglossy_. The same problem solved on multiple languages. + +## The Problem - Mathematicians Version +Let <img src="https://latex.codecogs.com/svg.latex?S:&space;\mathbb{N}\rightarrow&space;\mathbb{N}"/> be the sum of the digits of a positive integer in a _[base 10 positional number system](https://en.wikipedia.org/wiki/Positional_notation)_. We have: + +<img src="https://latex.codecogs.com/svg.latex?\forall&space;a,&space;b&space;\in&space;\mathbb{N},&space;S_{a&space;+&space;b}&space;\equiv&space;S_a&space;+&space;S_b&space;\;\(\textup{mod}\;&space;9&space;\)"/> + +### Addendum +This conjecture can be generalized for any _positional number system_. Check out `proof.pdf` for more information. + +## The Problem - Programmers Verison + +Let `S(n: uint) -> uint` be the sum of the digits of `n` in _[base 10](https://en.wikipedia.org/wiki/Decimal)_. Then, for all `a` and `b` of type `uint`, `S(a + b) - ( S(a) + S(b) ) % 9 == 0`. + +## Performance +The conjecture was [proved by exhaustion](https://en.wikipedia.org/wiki/Proof_by_exhaustion) for the interval <img src="https://latex.codecogs.com/svg.latex?[0,&space;10^4]"/> in multiple language implementations. The performance of each language was then avaliated as the following _(*)_: + +|Language |Milliseconds| +|--------------|------------| +|**Rust** |103 | +|**C** |113 | +|**Kotlin** |137 | +|**Go** |155 | +|**JavaScript**|656 | +|**Ruby** |9850 | +|**Python** |16032 | +|**Haskell** |28365 | + +_* out of date_
diff --git a/Rust/.gitignore b/Rust/.gitignore @@ -1,2 +1,2 @@ -/target -**/*.rs.bk +/target +**/*.rs.bk
diff --git a/Rust/Cargo.lock b/Rust/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "digital_sum" version = "0.1.0"
diff --git a/Rust/Cargo.toml b/Rust/Cargo.toml @@ -1,7 +1,7 @@ -[package] -name = "digital_sum" -version = "0.1.0" -authors = ["Gark Garcia <37553739+GarkGarcia@users.noreply.github.com>"] - -[dependencies] +[package] +name = "digital_sum" +version = "0.1.0" +authors = ["Gark Garcia <37553739+GarkGarcia@users.noreply.github.com>"] + +[dependencies] num_cpus = "1.0" \ No newline at end of file
diff --git a/Rust/src/main.rs b/Rust/src/main.rs @@ -1,118 +1,118 @@ -// 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. - -extern crate num_cpus; - -use std::{env, process, thread, sync::{Arc, mpsc::{self, Sender, Receiver}}}; - -const SUCCESS: i32 = 0; -const FAIL: i32 = 1; -const INVALID_INPUT: i32 = 2; - -fn main() { - let args: Vec<String> = env::args().collect(); - - if args.len() > 1 { - let max_str = args[1].clone(); - - // Assign the correct number of threads to run the application with - // The default is the number of cores in the machine - let n_cores = num_cpus::get_physical(); - let n_threads = if args.len() <= 2 { n_cores } else { - match args[2].trim().parse::<usize>() { - Ok(n_arg) => std::cmp::min(n_arg, n_cores), - Err(_) => n_cores - } - }; - - match max_str.trim().parse::<usize>() { - Ok(max) => if get_countrexpl(max, n_threads) { - process::exit(FAIL); - } else { - process::exit(SUCCESS); - }, - Err(_) => process::exit(INVALID_INPUT) - } - } else { - process::exit(INVALID_INPUT); - } -} - -/// Distributes calculations across threads and collect the results -fn get_countrexpl(max: usize, n_threads: usize) -> bool { - let sums_cache = Arc::new(get_sums(max)); - - if n_threads > 1 { - let (coutexpl_sender, coutexpl_reciever): (Sender<bool>, Receiver<bool>) = mpsc::channel(); - let mut child_threads = Vec::with_capacity(n_threads); - - for i in 0..n_threads { - let thread_countr_sd = coutexpl_sender.clone(); - let thread_sums = sums_cache.clone(); - - // By separating the interval [0..max] in subsections with the form [i + 0n, i + 1n, i + 2n, ...] we can ensure that every - // value will get tested on a single thread and that all threads will perform roughtly the same number of operations - let thread_range = (i..max).step_by(n_threads); - - let child = thread::spawn(move || thread_countr_sd.send(get_iter_countrexpl(thread_range, thread_sums, max)) - .expect(&format!("Thread n°{} was unable to sent a message trought the channel", i))); - - child_threads.push(child); - if let Ok(true) = coutexpl_reciever.recv() { - return true; - } - } - - for child in child_threads { - child.join().expect("Child thread panicked"); - } - - false - } else { - get_iter_countrexpl(0..max, sums_cache, max) - } -} - -/// Search for counterexamples among the items of a specif iterator. -fn get_iter_countrexpl<I: IntoIterator<Item = usize>>( - iter: I, - sums_cache: Arc<Vec<isize>>, - max: usize -) -> bool { - for a in iter { - for b in a..max { - let diff = sums_cache[a + b] - sums_cache[a] - sums_cache[b]; - - if diff % 9 != 0 { - return true; - } - } - } - - false -} - -fn sum_digits(n: usize) -> isize { - let mut sum = 0; - let mut part = n; - - while part != 0 { - sum += part % 10; - part /= 10; - } - - sum as isize -} - -fn get_sums(max: usize) -> Vec<isize> { - let range_max = 2 * (max + 1); - let mut output = Vec::with_capacity(range_max); - - for i in 0..range_max { - output.push(sum_digits(i)); - } - - output -}- \ No newline at end of file +// 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. + +extern crate num_cpus; + +use std::{env, process, thread, sync::{Arc, mpsc::{self, Sender, Receiver}}}; + +const SUCCESS: i32 = 0; +const FAIL: i32 = 1; +const INVALID_INPUT: i32 = 2; + +fn main() { + let args: Vec<String> = env::args().collect(); + + if args.len() > 1 { + let max_str = args[1].clone(); + + // Assign the correct number of threads to run the application with + // The default is the number of cores in the machine + let n_cores = num_cpus::get_physical(); + let n_threads = if args.len() <= 2 { n_cores } else { + match args[2].trim().parse::<usize>() { + Ok(n_arg) => std::cmp::min(n_arg, n_cores), + Err(_) => n_cores + } + }; + + match max_str.trim().parse::<usize>() { + Ok(max) => if get_countrexpl(max, n_threads) { + process::exit(FAIL); + } else { + process::exit(SUCCESS); + }, + Err(_) => process::exit(INVALID_INPUT) + } + } else { + process::exit(INVALID_INPUT); + } +} + +/// Distributes calculations across threads and collect the results +fn get_countrexpl(max: usize, n_threads: usize) -> bool { + let sums_cache = Arc::new(get_sums(max)); + + if n_threads > 1 { + let (coutexpl_sender, coutexpl_reciever): (Sender<bool>, Receiver<bool>) = mpsc::channel(); + let mut child_threads = Vec::with_capacity(n_threads); + + for i in 0..n_threads { + let thread_countr_sd = coutexpl_sender.clone(); + let thread_sums = sums_cache.clone(); + + // By separating the interval [0..max] in subsections with the form [i + 0n, i + 1n, i + 2n, ...] we can ensure that every + // value will get tested on a single thread and that all threads will perform roughtly the same number of operations + let thread_range = (i..max).step_by(n_threads); + + let child = thread::spawn(move || thread_countr_sd.send(get_iter_countrexpl(thread_range, thread_sums, max)) + .expect(&format!("Thread n°{} was unable to sent a message trought the channel", i))); + + child_threads.push(child); + if let Ok(true) = coutexpl_reciever.recv() { + return true; + } + } + + for child in child_threads { + child.join().expect("Child thread panicked"); + } + + false + } else { + get_iter_countrexpl(0..max, sums_cache, max) + } +} + +/// Search for counterexamples among the items of a specif iterator. +fn get_iter_countrexpl<I: IntoIterator<Item = usize>>( + iter: I, + sums_cache: Arc<Vec<isize>>, + max: usize +) -> bool { + for a in iter { + for b in a..max { + let diff = sums_cache[a + b] - sums_cache[a] - sums_cache[b]; + + if diff % 9 != 0 { + return true; + } + } + } + + false +} + +fn sum_digits(n: usize) -> isize { + let mut sum = 0; + let mut part = n; + + while part != 0 { + sum += part % 10; + part /= 10; + } + + sum as isize +} + +fn get_sums(max: usize) -> Vec<isize> { + let range_max = 2 * (max + 1); + let mut output = Vec::with_capacity(range_max); + + for i in 0..range_max { + output.push(sum_digits(i)); + } + + output +}
diff --git a/hla/conjecture.hla b/hla/conjecture.hla @@ -1,129 +1,129 @@ -program conjecture; - - #includeonce( "stdlib.hhf" ) - #includeonce( "w32\win32.hhf") - - ?@nodisplay := true; - ?@noalignstack := true; - -// This 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 interger. - -// data segments -storage - max :uns32; - sumAB :uns32; - sumA :uns32; - sumB :uns32; - timeStart :dword; - timeEnd :dword; - -static - err :boolean := false; - - -// input eax = number to sum -// returns sum in ebx -procedure sum_digits; - - // don't build a stack frame for this procedure - @nodisplay; @noframe; - -begin sum_digits; - - mov( 10, ecx ); - xor( ebx, ebx ); - while( eax ) do - xor( edx, edx ); - div( ecx ); - add( edx, ebx ); - endwhile; - ret; - -end sum_digits; - - - -begin conjecture; - - // read an unsigned integer from the user - forever - try - stdout.put ("enter an unsigned integer :>" ); - stdin.getu32(); - mov( eax, max ); - break; - anyexception; - stdout.newln(); - continue; - endtry; - endfor; - - - - stdout.put ("Loading ..." nl ); - w.GetTickCount(); - mov( eax, timeStart ); - - for( xor(esi, esi); esi <= max; inc( esi ) ) do - - // outer loop esi = 0 to max iterations - - for( mov(esi, edi); edi <= max; inc( edi ) ) do - - // inner loop. edi = esi to max iterations - - // get S(a+b) - mov( esi, eax ); - add( edi, eax ); - call sum_digits; - mov( ebx, sumAB ); - - // get S(a) - mov( esi, eax ); - call sum_digits; - mov( ebx, sumA ); - - // get S(b) - mov( edi, eax ); - call sum_digits; - mov( ebx, sumB ); - - // get S(a+b) - S(a) - S(b) - mov( sumAB, eax ); - sub( sumA, eax ); - sub( sumB, eax ); - - // sign extend into edx - cdq(); - mov( 9, ecx ); - idiv( ecx ); // signed division of edx:eax - test( edx, edx ); // is remainder zero? - if( @nz ) then - // if remainder is not zero, the conjecture is false - stdout.put ("Conjecture is disproved, here is the counter example :", (type uns32 eax), nl ); - mov( true, err ); - break; - endif; - endfor; - - breakif( err ); - - endfor; - - // if we get here, we looped through all the values and the - // conjecture is proved. - if( !err ) then - - w.GetTickCount(); - mov( eax, timeEnd ); - mov( timeEnd, eax ); - sub( timeStart, eax ); - stdout.put("Loaded in : ", (type uns32 eax), "ms, [1 Thread, no preprocessing]", nl); - stdout.put ("The conjecture is proved for all natural numbers smaller or equals to ", max, "!", nl ); - - endif; - -end conjecture; +program conjecture; + + #includeonce( "stdlib.hhf" ) + #includeonce( "w32\win32.hhf") + + ?@nodisplay := true; + ?@noalignstack := true; + +// This 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 interger. + +// data segments +storage + max :uns32; + sumAB :uns32; + sumA :uns32; + sumB :uns32; + timeStart :dword; + timeEnd :dword; + +static + err :boolean := false; + + +// input eax = number to sum +// returns sum in ebx +procedure sum_digits; + + // don't build a stack frame for this procedure + @nodisplay; @noframe; + +begin sum_digits; + + mov( 10, ecx ); + xor( ebx, ebx ); + while( eax ) do + xor( edx, edx ); + div( ecx ); + add( edx, ebx ); + endwhile; + ret; + +end sum_digits; + + + +begin conjecture; + + // read an unsigned integer from the user + forever + try + stdout.put ("enter an unsigned integer :>" ); + stdin.getu32(); + mov( eax, max ); + break; + anyexception; + stdout.newln(); + continue; + endtry; + endfor; + + + + stdout.put ("Loading ..." nl ); + w.GetTickCount(); + mov( eax, timeStart ); + + for( xor(esi, esi); esi <= max; inc( esi ) ) do + + // outer loop esi = 0 to max iterations + + for( mov(esi, edi); edi <= max; inc( edi ) ) do + + // inner loop. edi = esi to max iterations + + // get S(a+b) + mov( esi, eax ); + add( edi, eax ); + call sum_digits; + mov( ebx, sumAB ); + + // get S(a) + mov( esi, eax ); + call sum_digits; + mov( ebx, sumA ); + + // get S(b) + mov( edi, eax ); + call sum_digits; + mov( ebx, sumB ); + + // get S(a+b) - S(a) - S(b) + mov( sumAB, eax ); + sub( sumA, eax ); + sub( sumB, eax ); + + // sign extend into edx + cdq(); + mov( 9, ecx ); + idiv( ecx ); // signed division of edx:eax + test( edx, edx ); // is remainder zero? + if( @nz ) then + // if remainder is not zero, the conjecture is false + stdout.put ("Conjecture is disproved, here is the counter example :", (type uns32 eax), nl ); + mov( true, err ); + break; + endif; + endfor; + + breakif( err ); + + endfor; + + // if we get here, we looped through all the values and the + // conjecture is proved. + if( !err ) then + + w.GetTickCount(); + mov( eax, timeEnd ); + mov( timeEnd, eax ); + sub( timeStart, eax ); + stdout.put("Loaded in : ", (type uns32 eax), "ms, [1 Thread, no preprocessing]", nl); + stdout.put ("The conjecture is proved for all natural numbers smaller or equals to ", max, "!", nl ); + + endif; + +end conjecture;
diff --git a/script.js b/script.js @@ -1,39 +1,39 @@ -// This script 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 interger. - -function sumDigits() { - if (isNaN(this) || !isFinite(this) || !this) - throw new TypeError - - let parc = Math.abs(this), sum = 0; - - while (parc > 0) { - sum += parc % 10; - parc = Math.floor(parc / 10); - } - - return sum; -} - -function getSums(max) { - const output = [], maxRange = 2 * (max + 1); - - for (let i = 0; i <= maxRange; i++) - output.push(sumDigits(i)); - - return output; -} - -export function getCounterExp(max) { - const sums = getSums(max); - - for (let a = 1; a <= max; a++) - for (let b = a; b <= max; b++) { - const diff = sums[a + b] - (sums[a] + sums[b]); - if (diff % 9 !== 0) return true; - } - - return false; -}- \ No newline at end of file +// This script 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 interger. + +function sumDigits(n) { + if (isNaN(n) || !isFinite(n) || !n) + throw new TypeError + + let parc = Math.abs(n), sum = 0; + + while (parc > 0) { + sum += parc % 10; + parc = Math.floor(parc / 10); + } + + return sum; +} + +function getSums(max) { + const output = [], maxRange = 2 * (max + 1); + + for (let i = 0; i <= maxRange; i++) + output.push(sumDigits(i)); + + return output; +} + +export function getCounterExp(max) { + const sums = getSums(max); + + for (let a = 1; a <= max; a++) + for (let b = a; b <= max; b++) { + const diff = sums[a + b] - (sums[a] + sums[b]); + if (diff % 9 !== 0) return true; + } + + return false; +}
diff --git a/script.pl b/script.pl @@ -1,29 +1,29 @@ -% The following script 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. - -sum_digits(X, Y) :- sum_digits_acc(X, 0, Y). - -sum_digits_acc(X, A, Y) :- X < 10, !, Y is A + X. -sum_digits_acc(X, A, Y) :- - Q = X div 10, - R = X mod 10, - A2 = A + R, - sum_digits_acc(Q, A2, Y). - -test_pair(A, B) :- - R = 0, - AB = A + B, - sum_digits(A, SA), - sum_digits(B, SB), - sum_digits(AB, SC), - SAB = SA + SB, - D = SC - SAB, - R =:= D mod 9. - -iter(A, B) :- - forall(between(0, B, X), test_pair(A, X)). - -conjecture(M) :- +% The following script 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. + +sum_digits(X, Y) :- sum_digits_acc(X, 0, Y). + +sum_digits_acc(X, A, Y) :- X < 10, !, Y is A + X. +sum_digits_acc(X, A, Y) :- + Q = X div 10, + R = X mod 10, + A2 = A + R, + sum_digits_acc(Q, A2, Y). + +test_pair(A, B) :- + R = 0, + AB = A + B, + sum_digits(A, SA), + sum_digits(B, SB), + sum_digits(AB, SC), + SAB = SA + SB, + D = SC - SAB, + R =:= D mod 9. + +iter(A, B) :- + forall(between(0, B, X), test_pair(A, X)). + +conjecture(M) :- forall(between(0, M, X), iter(X, X)). \ No newline at end of file
diff --git a/script.py b/script.py @@ -1,34 +1,34 @@ -# This script 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 interger. - -def sum_digits(n: int) -> int: - parc = abs(n) - sum_d = 0 - - while parc > 0: - sum_d += parc % 10 - parc //= 10 - - return sum_d - -def get_sums(max: int) -> list: - output = [] - - for i in range(2 * max): - output.append(sum_digits(i)) - - return output - -def get_counterexmpl(max: int) -> bool: - sums = get_sums(max) - - for a in range(max + 1): - for b in range(a, max + 1): - diff = sums[a + b] - sums[a] - sums[b] - - if not diff % 9 == 0: - return True - - return False +# This script 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 interger. + +def sum_digits(n: int) -> int: + parc = abs(n) + sum_d = 0 + + while parc > 0: + sum_d += parc % 10 + parc //= 10 + + return sum_d + +def get_sums(max: int) -> list: + output = [] + + for i in range(2 * max): + output.append(sum_digits(i)) + + return output + +def get_counterexmpl(max: int) -> bool: + sums = get_sums(max) + + for a in range(max + 1): + for b in range(a, max + 1): + diff = sums[a + b] - sums[a] - sums[b] + + if not diff % 9 == 0: + return True + + return False
diff --git a/script.rb b/script.rb @@ -1,43 +1,43 @@ -# This script 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 interger. - -def sumDigits(i) - part = i.abs() - sum = 0 - - while part > 0 - d, r = part.divmod(10) - sum += r - part = d - end - - return sum -end - -def getSums(max) - output = [] - - for i in 0..((max + 1) * 2) - output << sumDigits(i) - end - - return output -end - -def get_counterexpl(max) - sums = getSums(max) - - for a in (0..max) - for b in (a..max) - diff = sums[a + b] - sums[a] - sums[b] - - if diff % 9 != 0 - return true - end - end - end - - return false +# This script 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 interger. + +def sumDigits(i) + part = i.abs() + sum = 0 + + while part > 0 + d, r = part.divmod(10) + sum += r + part = d + end + + return sum +end + +def getSums(max) + output = [] + + for i in 0..((max + 1) * 2) + output << sumDigits(i) + end + + return output +end + +def get_counterexpl(max) + sums = getSums(max) + + for a in (0..max) + for b in (a..max) + diff = sums[a + b] - sums[a] - sums[b] + + if diff % 9 != 0 + return true + end + end + end + + return false end \ No newline at end of file
diff --git a/x86/PROGRAM.ASM b/x86/PROGRAM.ASM @@ -1,413 +1,413 @@ -.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, 0ah - ;int 21 - 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 +.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, 0ah + ;int 21 + 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