diff --git a/haskell/README.org b/haskell/README.org new file mode 100644 index 0000000..162216a --- /dev/null +++ b/haskell/README.org @@ -0,0 +1,3 @@ +#+TITLE: Haskell + + - [[./state-monad.hs][state-monad.hs]]: Demo of state monad using postfix expression evaluator diff --git a/haskell/state-monad.hs b/haskell/state-monad.hs new file mode 100644 index 0000000..815f05a --- /dev/null +++ b/haskell/state-monad.hs @@ -0,0 +1,70 @@ +-- | Demo of state monad + +import Data.Char +import GHC.Float +import Control.Monad.State + + +-- | Process next input character +chrToOp + :: (Num a, Fractional a) + => Char -- ^ Character denoting an operation + -> (a -> a -> a) -- ^ Function corresponding to the operation + +chrToOp ch = + case ch of + '+' -> (+) + '-' -> (-) + '*' -> (*) + '/' -> (/) + + +-- | Process next input character +process_inp + :: Char -- ^ Next input character + -> [Float] -- ^ Current state of stack + -> [Float] -- ^ New state of stack + +process_inp ch st + | isDigit ch = [int2Float $ digitToInt ch] ++ st + | elem ch "+-*/" = [(chrToOp ch) (st!!1) (st!!0)] ++ (tail (tail st)) + | otherwise = st + + +postfixeval + :: String -- ^ Input string + -> State [Float] Float + +postfixeval [] = do + st <- get + return $ head st + +postfixeval (x:xs) = do + st <- get + let newst = process_inp x st + put newst + postfixeval xs + +-- main = print $ fst $ runState (postfixeval "32+") [] +main = do + putStrLn "Enter the postfix expression:" + inp <- getLine + print $ fst $ runState (postfixeval inp) [] + + +{- +λ> fst $ runState (postfixeval "32+2*6-2/") [] +2.0 + +λ> fst $ runState (postfixeval "32+") [] +-} + +{- +Enter the postfix expression: +32+ +5.0 + +Enter the postfix expression: +32+2*6-2/ +2.0 +-} diff --git a/misc/README.org b/misc/README.org new file mode 100644 index 0000000..3c2aa9f --- /dev/null +++ b/misc/README.org @@ -0,0 +1,7 @@ +#+TITLE: Misc + +ACL2 proof assistant: + - hello-acl2.lisp + +Maude model cheker: + - my-nat.maude diff --git a/misc/hello-acl2.lisp b/misc/hello-acl2.lisp new file mode 100644 index 0000000..9948139 --- /dev/null +++ b/misc/hello-acl2.lisp @@ -0,0 +1,6 @@ +(defun mem (e x) + (if (consp x) + (if (equal e (car list)) + t + (mem e (cdr x)) + nil))) diff --git a/misc/my-nat.maude b/misc/my-nat.maude new file mode 100644 index 0000000..ba31038 --- /dev/null +++ b/misc/my-nat.maude @@ -0,0 +1,19 @@ +--- From maude docs + +--- This is a comment. +*** This is a comment too. + +fmod SIMPLE-NAT is + sort Nat . + op zero : -> Nat . + op s_ : Nat -> Nat . + op _+_ : Nat Nat -> Nat . + + + --- variables + vars N M : Nat . + + --- rewrite rules + eq zero + N = N . + eq s N + M = s (N + M) . +endfm diff --git a/python/binary.py b/python/binary.py new file mode 100644 index 0000000..db79e5b --- /dev/null +++ b/python/binary.py @@ -0,0 +1,11 @@ +def tobin(n : int) -> "List[int]": + rv = [] + while n>0: + rv.append(n%2) + n//=2 + return rv + +for i in range(17): + rv = tobin(i) + rv.reverse() + print(rv) diff --git a/python/cracklepop/cracklepop.py b/python/cracklepop/cracklepop.py new file mode 100644 index 0000000..7563be7 --- /dev/null +++ b/python/cracklepop/cracklepop.py @@ -0,0 +1,38 @@ +""" +CracklePop! + +A program that prints out the numbers 1 to 100 (inclusive). +If the number is divisible by 3, print Crackle instead of the number. +If it's divisible by 5, print Pop. +If it's divisible by both 3 and 5, print CracklePop. +""" + + +def get_msg(num: int) -> str: + """ + Find message to be printed for the number. + Return "Crackle", "Pop" and "CracklePop" if num is divisible by 3, 5 + and 15 respectively, otherwise return empty string. + """ + msg = "" + if num % 3 == 0: + msg += "Crackle" + if num % 5 == 0: + msg += "Pop" + return msg + + +def cracklepop(limit: int) -> None: + """ + Print CracklePop for numbers from 1 to limit (inclusive) + """ + for num in range(1, limit+1): + msg = get_msg(num) + if msg: + print(msg) + else: + print(num) + + +if __name__ == "__main__": + cracklepop(100) diff --git a/python/cracklepop/test_crackle_pop.py b/python/cracklepop/test_crackle_pop.py new file mode 100644 index 0000000..13be4fb --- /dev/null +++ b/python/cracklepop/test_crackle_pop.py @@ -0,0 +1,35 @@ +import pytest + +import cracklepop + + +@pytest.mark.parametrize("num, expected", [ + (51, "Crackle"), # divisible by 3 + (65, "Pop"), # divisible by 5 + (75, "CracklePop"), # divisible by both 3 and 5 + (82, "") # not divisible by 3, 5 and 15 +]) +def test_get_msg(num, expected): + assert cracklepop.get_msg(num) == expected + + +def test_cracklepop(capsys): + limit = 15 + expected = """1 +2 +Crackle +4 +Pop +Crackle +7 +8 +Crackle +Pop +11 +Crackle +13 +14 +CracklePop +""" + cracklepop.cracklepop(limit) + assert capsys.readouterr().out == expected diff --git a/python/interests.py b/python/interests.py new file mode 100644 index 0000000..385a0b2 --- /dev/null +++ b/python/interests.py @@ -0,0 +1,45 @@ +""" +Functions to find simple and compound interests. +""" + +def comp_interest(principal: float, + rate: float, + comp_freq: int, + duration: float) -> float: + """ + principal: principal amount + rate: Rate interest as float (100% is 100) + duration: Duration in years + comp_freq: Number of compounding periods in a year + + interest = principal*((1 + rate/100)**n) - principal + """ + rate /= 100 * comp_freq + rv = (1 + rate) ** (comp_freq * duration) + rv = principal * rv + rv -= principal + return rv + +def simp_interest(principal: float, + rate: float, + duration: float) -> float: + """ + principal: principal amount + rate: Rate interest as float (100% is 100) + duration: Duration in years + comp_freq: Number of compounding periods in a year + + interest = principal * duration * rate + """ + return principal * duration * rate/100 + + +#import pytest +# +#@pytest.mark.parametrize("principal,rate,comp_freq,duration,expected", [ +# (12000, 10, 2, 1.5, 1891.5), +# (1000, 20, 1, 2, 440.0), +#]) +#def test_comp_interest(principal, rate, comp_freq, duration, expected): +# rv = comp_interest(principal, rate, comp_freq, duration) +# assert round(rv, 5) == expected diff --git a/python/lucas.py b/python/lucas.py new file mode 100644 index 0000000..14820a1 --- /dev/null +++ b/python/lucas.py @@ -0,0 +1,48 @@ +def aCb(a: int, b: int) -> int: + abin = [int(x) for x in bin(a)[2:]] + bbin = [int(x) for x in bin(b)[2:]] + alen = len(abin) + blen = len(bbin) + maxlen = max(alen, blen) + abin = [0] * (maxlen - alen) + abi, safe=""n + bbin = [0] * (maxlen - blen) + bbin + acc = 1 + for x,y in zip(abin, bbin): + if x==0 and y==1: + return 0 + return 1 + +def oneline(level: int) -> "List[Int]": + """ + level starts from 0. + """ + return [aCb(level,j) for j in range(level+1)] + +def pascal(n: int): + for i in range(n): + print(" "*(n-i), end="") + l = oneline(i) + for x in l: + print(f" {x}", end="") + print() + +pascal(50) + +""" + 1 + 1 1 + 1 0 1 + 1 1 1 1 + 1 0 0 0 1 + 1 1 0 0 1 1 + 1 0 1 0 1 0 1 + 1 1 1 1 1 1 1 1 + 1 0 0 0 0 0 0 0 1 + 1 1 0 0 0 0 0 0 1 1 + 1 0 1 0 0 0 0 0 1 0 1 + 1 1 1 1 0 0 0 0 1 1 1 1 + 1 0 0 0 1 0 0 0 1 0 0 0 1 + 1 1 0 0 1 1 0 0 1 1 0 0 1 1 + 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +""" diff --git a/python/pyconau2020/README.md b/python/pyconau2020/README.md new file mode 100644 index 0000000..441f6d3 --- /dev/null +++ b/python/pyconau2020/README.md @@ -0,0 +1,18 @@ +# Rube Codeberg entry + +Made as an entry for the 'Rube Codeberg' competition conducted as part of the +11th PyCon Australia ([PyConline AU 2020](https://2020.pycon.org.au/program/sun/#rube-codeberg-competition). + +The name of the contest is named after [Rube Goldberg machines](https://en.wikipedia.org/wiki/Rube_Goldberg_machine), which are in turn named after the American cartoonist [Rube Goldberg](https://en.wikipedia.org/wiki/Rube_Goldberg). + +## Objective +The aim of the contest was to make a 'hello world' program in Python in as complicated +a way as possible. + + +## Cool entries +There were lot of cool entries for the competition (but I forgot which among them were the winning entries). + +I couldn't dig all of them up but did manage to find this one: + + - [By James Constable](https://github.com/jamesconstable/rube-codeberg) diff --git a/python/pyconau2020/helloworld.py b/python/pyconau2020/helloworld.py new file mode 100644 index 0000000..4889f87 --- /dev/null +++ b/python/pyconau2020/helloworld.py @@ -0,0 +1,104 @@ +""" +Prints "Hello world" using html pulled from a copy of the Pyconline program +page for Sunday. Uses beautiful soup. + +BeautifulSoup is imported dynamically. +Requires internet to work. + +Does the following: + + - Get html of web page containing guidelines for Rube Codeberg with urllib. + - Open the source code of this program, to get the name of a module to + be imported (beautiful soup) + - Import BeautifulSoup dynamically using importlib + (thanks to Shivashis' talk) + - Parse the message to be printed using beautiful soup. + - Construct AST for a print function call with ast module. + (thanks to Katie's talk) + - Convert ast to code object which is then executed. +""" + +from typing import List, Tuple +import ast +import importlib +import urllib.request + +# from bs4 import BeautifulSoup # imported dynamically + +URL = "https://2020.pycon.org.au/program/sun/" + + +def get_html(url: str) -> str: + """Extract html from a url""" + with urllib.request.urlopen(url) as response: + bytestr = response.read() + return bytestr.decode('utf-8') + return None + + +def get_bs_name_from_src() -> List[str]: + """ + Extract the words 'beautiful' and 'soup' from this file and + return them as a list. + """ + with open(__file__) as fsrc: + lines = fsrc.readlines() + third_line_items = lines[2].split()[-2:] # ['beautiful', 'soup'] + third_line_items[-1] = third_line_items[-1].replace('.', '') + return third_line_items + + +def get_bs_class(): + """Import bs4 dynamically and return BeautifulSoup class""" + name_list = get_bs_name_from_src() + mod_name = ''.join(word[0] for word in name_list) + "4" + class_name = ''.join(word.capitalize() for word in name_list) + + bs4 = importlib.import_module(mod_name) + return getattr(bs4, class_name) + + +def get_fn_and_msg(html_str: str) -> Tuple[str, str]: + """ + Generate function name and extract message from the html string. + + Use the first list item in the unordered list of rules in the page. + + ie, + + ``` + Print "Hello world!" on the screen (somehow - we don't care how + - doesn't have to be the console) as a result of being executed + ``` + """ + BeautifulSoup = get_bs_class() + soup = BeautifulSoup(html_str, "html.parser") + msg = soup.main.find_all("ul", limit=2)[-1].li.strong.string + fn_name, msg = msg.split(' ', maxsplit=1) + fn_name = fn_name.lower() # Print -> print + msg = msg.replace('"', ' ').strip() # "Hello world!" -> Hello world! + return fn_name, msg + + +def get_code(fn_name_str: str, msg: str): + """ + Generate AST for + + >>> fn_name_str(msg) # print("Hello world!") + + and return it as code object + """ + fn_name = ast.Name(id=fn_name_str, ctx=ast.Load()) + fn_args = ast.Str(s=msg) + fn_call = ast.Call(func=fn_name, args=[fn_args], keywords=[]) + expr = ast.Expr(value=fn_call) + module = ast.Module(body=[expr], type_ignores=[]) + ast.fix_missing_locations(module) + return compile(module, '', 'exec') + + +if __name__ == "__main__": + html_text = get_html(f"http://web.archive.org/web/20200905141404/{URL}") + func_name, message = get_fn_and_msg(html_text) + code = get_code(func_name, message) + exec(code) diff --git a/python/pyconau2020/others_incomplete.md b/python/pyconau2020/others_incomplete.md new file mode 100644 index 0000000..2c71cb2 --- /dev/null +++ b/python/pyconau2020/others_incomplete.md @@ -0,0 +1,7 @@ + + + + - [https://github.com/ewenmcneill/rube-codeberg-fsm](https://github.com/ewenmcneill/rube-codeberg-fsm) + - https://gist.github.com/r1chardj0n3s/f7cae394a1e6c759c9898fee8d7dc0b2 + - https://github.com/wolfric83/pyconlineAU2020-RubeCodeberg + - https://gist.github.com/dwurf/95cdfdf5cd4d1890c8526cea2423cfeb diff --git a/python/tictactoe/README.md b/python/tictactoe/README.md new file mode 100644 index 0000000..f4bd0e4 --- /dev/null +++ b/python/tictactoe/README.md @@ -0,0 +1 @@ +A simple tic tac toe game. diff --git a/python/tictactoe/test_ttt.py b/python/tictactoe/test_ttt.py new file mode 100644 index 0000000..c631785 --- /dev/null +++ b/python/tictactoe/test_ttt.py @@ -0,0 +1,75 @@ +import textwrap + +import pytest + +import ttt + + +@pytest.fixture +def game(): + return ttt.TicTacToe(players=[("User", 'O'), ("PC", 'X')]) + + +@pytest.mark.parametrize('grid,expected', [ + (['O', None, 'X', + 'X', 'O', None, + None, None, 'O'], 1), + (['O', None, 'X', + 'X', 'O', None, + None, None, 'X'], 0), + (['O', 'X', 'X', + 'X', 'O', 'O', + 'O', 'X', 'X'], -1), +]) +def test_is_over(game, grid, expected): + game.grid = grid + game._empty = sum([1 for x in grid if x is None]) + assert game._is_over() == expected + + +class TestNextTurn: + @pytest.mark.parametrize('grid, cell_idx, expected', [ + (['O', 'X', 'X', + 'X', None, 'O', + 'O', 'X', 'X'], 4, -1), + ([None, 'X', 'X', + 'X', None, 'O', + 'O', 'X', 'X'], 0, 0), + (['O', 'X', 'X', + 'X', None, 'O', + 'O', 'X', 'O'], 4, 1), + ]) + def test_valid(self, game, grid, cell_idx, expected): + game.grid = grid + game._empty = sum([1 for x in grid if x is None]) + assert game.next_turn(cell_idx) == expected + + @pytest.mark.parametrize('grid, cell_idx', [ + (['O', 'X', 'X', + 'X', None, 'O', + 'O', 'X', 'X'], 1), + (['O', 'X', 'X', + 'X', None, 'O', + 'O', 'X', 'X'], 11), + ]) + def test_invalid(self, game, grid, cell_idx): + game.grid = grid + game._empty = sum([1 for x in grid if x is None]) + with pytest.raises(ValueError): + game.next_turn(cell_idx) + + +def test_display(capsys): + grid = [None, 'X', 'X', + 'X', None, 'O', + 'O', 'X', 'X'] + grid_str = """ + | X | X + ----------- + X | | O + ----------- + O | X | X""" + grid_str = textwrap.dedent(grid_str).strip('\n') + ttt.display(grid) + captured = capsys.readouterr() + assert captured.out.strip('\n') == grid_str.strip('\n') diff --git a/python/tictactoe/ttt.py b/python/tictactoe/ttt.py new file mode 100644 index 0000000..0c1b692 --- /dev/null +++ b/python/tictactoe/ttt.py @@ -0,0 +1,144 @@ +""" +Simple TicTacToe game + +Needs Python>=3.6 +""" + +from typing import List, Tuple + + +class TicTacToe: + """ + Represents a game of tic-tac-toe. + """ + # Possbile winning configurations + _WINNING_POS = [ + [0, 1, 2], # top horizontal + [3, 4, 5], # middle horizontal + [6, 7, 8], # bottom horizontal + + [0, 3, 6], # left vertical + [1, 4, 7], # middle vertical + [2, 5, 8], # right vertical + + [0, 4, 8], # main diagonal + [2, 4, 6] # anti-diagonal + ] + + def __init__(self, players: List[Tuple[str, str]]): + """ + TicTacToe grid is represented with the grid attribute as a list of + 9 elements. + Empty cell have None value. + + players: a list of exactly two elements where each element is a tuple + of two strings: player name and player symbol + The first player in this list will get the first turn. + Player symbols must be strings of length 1. + + turn: index in the players list corresponding to the details of the + player who should play next. + + Raises ValueError on invalid player info. + """ + if len(players) != 2: + raise ValueError(f"Exactly 2 players needed. Got {len(players)}") + + # Check if player details are valid + for player_info in players: + count = len(player_info) + if count != 2: + raise ValueError(f"player tuple has 2 values. Got {count}") + + symbol = player_info[1] + if len(symbol) != 1: + raise ValueError(f"{symbol}: player symbol is a single char") + + # Assign attributes + self.players = players + self.grid = [None for _ in range(9)] + self.turn = 0 + self._empty = 9 # Number of empty cells + + def _is_over(self) -> int: + """ + Helper function for next_turn() that determines a game over condition. + + Returns 0 if game is not over, 1 if game is over with a winner + and -1 if there is a tie. + """ + symbol = self.players[self.turn][1] + for win_pos in self._WINNING_POS: + if all([self.grid[pos] == symbol for pos in win_pos]): + return 1 # a player won + + if self._empty == 0: + return -1 # a tie + + return 0 + + def next_turn(self, cell_idx: str) -> int: + """ + Represents one turn in the game. + + Accepts the index of chosen cell as a string. + Indexing starts from 0. + + Returns 0 if game is not over, 1 if game is over with a winner + and -1 if there is a tie. + + Raises ValueError if cell index is invalid. + """ + cell = int(cell_idx) + if cell < 0 or cell > 8: + raise ValueError(f"{cell}: Invalid cell index") + + if self.grid[cell] is not None: + raise ValueError("Cell already taken!") + + # Assign current player's symbol to cell + self.grid[cell] = self.players[self.turn][1] + self._empty -= 1 + + status = self._is_over() + if status == 0: + self.turn = 1 if self.turn == 0 else 0 + elif status < 0: + self.turn = None + return status + + +def display(grid: List[int]) -> None: + """Displays the grid""" + for row_num in range(3): + row = grid[row_num * 3: (row_num * 3) + 3] + row = [elem if elem is not None else ' ' for elem in row] + row_str = " " + ' | '.join(row) + print(row_str) + if row_num < 2: + print('-' * (len(row_str)+1)) + + +def play(game: TicTacToe) -> None: + """Event loop of the game""" + display(game.grid) + cell = input(f"{game.players[game.turn][0]}'s turn. Choose a cell: ") + while True: + try: + status = game.next_turn(cell) + except ValueError as verr: + print(verr) + else: + if status != 0: + break + display(game.grid) + cell = input(f"{game.players[game.turn][0]}'s turn. Choose a cell: ") + if game.turn is None: + print("Game tied...") + else: + print(f"{game.players[game.turn][0]} won!") + + +if __name__ == "__main__": + ttt = TicTacToe(players=[("User", 'O'), ("PC", 'X')]) + play(ttt) diff --git a/risc-v/README.md b/risc-v/README.md new file mode 100644 index 0000000..ff2133c --- /dev/null +++ b/risc-v/README.md @@ -0,0 +1,7 @@ +#+TITLE: RISC-V +#+LINK: l1 https://github.com/TheThirdOne/rars + +Run with [[l1][RARS]]. + + - [[./loop.asm][loop.asm]]: A loop + - [[./factorial.asm][factorial.asm]]: Factorial of a number diff --git a/risc-v/factorial.asm b/risc-v/factorial.asm new file mode 100644 index 0000000..674570e --- /dev/null +++ b/risc-v/factorial.asm @@ -0,0 +1,29 @@ +# long long int fact (long long int n) { +# if (n < 1) { +# return f; +# } else { +# return n * fact(n - 1); +# } +# } + +.global main +.data + +.text + +fact: + bgt x10, x0, recurse # non-base case: n > 0 + addi x10, x0, 1 # return 1 +recurse: + addi x2, x2, -16 # expand stack (x2 is SP) + sw x10, 8(x2) # save n to stack + sw x1, 0(x2) # save return address to stack + addi x5, x10, -1 # calculate (n - 1) + add x10, x5, x0 # set up (n-1) as argument to next function call + jal x1, fact # recursive function call + lw x1, 0(x2) # retrieve original return address + lw x5, 8(x2) # retrieve original n + mul x10, x5, x10 # set up return value as (n * fact(n-1)) + # mul available only in RV64M mulitply extension +over: + jalr x0, 0(x1) # return from fact() to caller function diff --git a/risc-v/loop.asm b/risc-v/loop.asm new file mode 100644 index 0000000..ac0af3c --- /dev/null +++ b/risc-v/loop.asm @@ -0,0 +1,25 @@ +# for(i=0; i<100; ++i) { +# a[i] = b[i] + c; +# } + +.global main +.data + +.text +main: + addi x6, x0, 100 + addi x5, x0, 10 + sw x5, 0(x6) + addi x5, x5, 1 + sw x5, 8(x6) + +begin: + addi x5, x0, 80 + add x6, x0, x0 +loop: add x8, x28, x6 + add x7, x29, x6 + lw x7, 0(x7) + add x7, x7, x30 + sw x7, 0(x8) + addi x6, x6, 8 + bne x6, x5, loop diff --git a/rust/README.org b/rust/README.org new file mode 100644 index 0000000..998b689 --- /dev/null +++ b/rust/README.org @@ -0,0 +1,3 @@ +#+TITLE: Rust + + - [[./traits.rs][traits.rs]]: Traits in rust diff --git a/rust/aoc2019/README.md b/rust/aoc2019/README.md new file mode 100644 index 0000000..6917a83 --- /dev/null +++ b/rust/aoc2019/README.md @@ -0,0 +1 @@ +Just an attempt at AOC2019 with rust. diff --git a/rust/aoc2019/d01p1.rs b/rust/aoc2019/d01p1.rs new file mode 100644 index 0000000..ccccab5 --- /dev/null +++ b/rust/aoc2019/d01p1.rs @@ -0,0 +1,42 @@ +/* https://adventofcode.com/2019/day/1 (part 1)*/ + +fn main() { + // 100 elements + let arr: [i32; 100] = [ + 95249, 126697, 77237, 80994, 91186, 53823, 115101, 130919, 88127, + 141736, 53882, 67432, 94292, 73223, 139947, 66450, 55710, 128647, + 73874, 57163, 139502, 140285, 119987, 125308, 77561, 74573, 85364, + 92991, 102935, 71259, 99622, 118876, 124482, 148442, 77664, 90453, + 111933, 110449, 74172, 148641, 58574, 135365, 84703, 81077, 65290, + 136749, 127256, 94872, 143534, 81702, 59493, 72365, 69497, 149082, + 79552, 78509, 73759, 147439, 97535, 118952, 114301, 104401, 95080, + 100907, 132914, 136096, 52451, 70544, 120717, 107010, 76840, 51324, + 135258, 73985, 118067, 86602, 95127, 51182, 84838, 60430, 86347, + 140487, 147777, 85143, 114215, 100410, 126504, 69630, 123656, 108886, + 144192, 123620, 147217, 146090, 101966, 80577, 62193, 143331, 79947, + 93518 + ]; + + + let mut fuel: i32 = 0; + + for i in 0..100 { + fuel += arr[i] / 3 - 2; + } + println!("{}", fuel); + +} +/* +# Equivalent Python program + +arr = [95249, 126697, ... + ..., 143331, 79947, + 93518] + +fuel = 0 + +for mass in arr: + fuel += mass // 3 - 2 + +print(fuel) +*/ diff --git a/rust/aoc2019/d01p2.rs b/rust/aoc2019/d01p2.rs new file mode 100644 index 0000000..4c62b66 --- /dev/null +++ b/rust/aoc2019/d01p2.rs @@ -0,0 +1,36 @@ +/* https://adventofcode.com/2019/day/1 (part 2)*/ + +fn recurse(mass: i32) -> i32 { + let fuel: i32 = mass / 3 - 2; + if fuel < 0 { + return 0 + } + fuel + recurse(fuel) +} + +fn main() { + // 100 elements + let arr: [i32; 100] = [ + 95249, 126697, 77237, 80994, 91186, 53823, 115101, 130919, 88127, + 141736, 53882, 67432, 94292, 73223, 139947, 66450, 55710, 128647, + 73874, 57163, 139502, 140285, 119987, 125308, 77561, 74573, 85364, + 92991, 102935, 71259, 99622, 118876, 124482, 148442, 77664, 90453, + 111933, 110449, 74172, 148641, 58574, 135365, 84703, 81077, 65290, + 136749, 127256, 94872, 143534, 81702, 59493, 72365, 69497, 149082, + 79552, 78509, 73759, 147439, 97535, 118952, 114301, 104401, 95080, + 100907, 132914, 136096, 52451, 70544, 120717, 107010, 76840, 51324, + 135258, 73985, 118067, 86602, 95127, 51182, 84838, 60430, 86347, + 140487, 147777, 85143, 114215, 100410, 126504, 69630, 123656, 108886, + 144192, 123620, 147217, 146090, 101966, 80577, 62193, 143331, 79947, + 93518 + ]; + + + let mut fuel: i32 = 0; + + for i in 0..100 { + fuel += recurse(arr[i]); + } + + println!("{}", fuel); +} diff --git a/rust/aoc2019/d02p1.rs b/rust/aoc2019/d02p1.rs new file mode 100644 index 0000000..0b9a5c5 --- /dev/null +++ b/rust/aoc2019/d02p1.rs @@ -0,0 +1,46 @@ +/* https://adventofcode.com/2019/day/2 (part 1) */ + +fn main() { + let mut list = vec![ + 1, 12, 2, 3, 1, 1, 2, 3, 1, 3, 4, 3, 1, 5, 0, 3, 2, 1, 9, 19, 1, 10, 19, + 23, 2, 9, 23, 27, 1, 6, 27, 31, 2, 31, 9, 35, 1, 5, 35, 39, 1, 10, 39, + 43, 1, 10, 43, 47, 2, 13, 47, 51, 1, 10, 51, 55, 2, 55, 10, 59, 1, 9, + 59, 63, 2, 6, 63, 67, 1, 5, 67, 71, 1, 71, 5, 75, 1, 5, 75, 79, 2, 79, + 13, 83, 1, 83, 5, 87, 2, 6, 87, 91, 1, 5, 91, 95, 1, 95, 9, 99, 1, 99, + 6, 103, 1, 103, 13, 107, 1, 107, 5, 111, 2, 111, 13, 115, 1, 115, 6, + 119, 1, 6, 119, 123, 2, 123, 13, 127, 1, 10, 127, 131, 1, 131, 2, 135, + 1, 135, 5, 0, 99, 2, 14, 0, 0 + ]; + + for i in (0..list.len()).step_by(4) { + if list[i] == 1 { + // addition + let r = list[i+3]; + list[r] = list[list[i+1]] + list[list[i+2]]; + } else if list[i] == 2 { + // multiplication + let r = list[i+3]; + list[r] = list[list[i+1]] * list[list[i+2]]; + } else if list[i] == 99 { + break; + } + } + println!("{}", list[0]); +} +/* +# Equivalent Python program + +arr = [1, 12, 2, 3, ... + ... + 1, 135, 5, 0, 99, 2, 14, 0, 0] + +for i in range(0, len(arr), 4): + if arr[i] == 1: + arr[arr[i+3]] = arr[arr[i+1]] + arr[arr[i+2]] + elif arr[i] == 2: + arr[arr[i+3]] = arr[arr[i+1]] * arr[arr[i+2]] + elif arr[i] == 99: + break + +print(arr[0]) +*/ diff --git a/rust/aoc2019/d02p2.rs b/rust/aoc2019/d02p2.rs new file mode 100644 index 0000000..da89d9d --- /dev/null +++ b/rust/aoc2019/d02p2.rs @@ -0,0 +1,30 @@ +/* https://adventofcode.com/2019/day/2 (part 2)*/ + +fn main() { + let mut list = vec![ + 1, 71, 95, 3, 1, 1, 2, 3, 1, 3, 4, 3, 1, 5, 0, 3, 2, 1, 9, 19, 1, 10, 19, + 23, 2, 9, 23, 27, 1, 6, 27, 31, 2, 31, 9, 35, 1, 5, 35, 39, 1, 10, 39, + 43, 1, 10, 43, 47, 2, 13, 47, 51, 1, 10, 51, 55, 2, 55, 10, 59, 1, 9, + 59, 63, 2, 6, 63, 67, 1, 5, 67, 71, 1, 71, 5, 75, 1, 5, 75, 79, 2, 79, + 13, 83, 1, 83, 5, 87, 2, 6, 87, 91, 1, 5, 91, 95, 1, 95, 9, 99, 1, 99, + 6, 103, 1, 103, 13, 107, 1, 107, 5, 111, 2, 111, 13, 115, 1, 115, 6, + 119, 1, 6, 119, 123, 2, 123, 13, 127, 1, 10, 127, 131, 1, 131, 2, 135, + 1, 135, 5, 0, 99, 2, 14, 0, 0 + ]; + //let bckup = list.clone(); + + for i in (0..list.len()).step_by(4) { + if list[i] == 1 { + // addition + let r = list[i+3]; + list[r] = list[list[i+1]] + list[list[i+2]]; + } else if list[i] == 2 { + // multiplication + let r = list[i+3]; + list[r] = list[list[i+1]] * list[list[i+2]]; + } else if list[i] == 99 { + break; + } + } + println!("{}", 100 * list[1] + list[2]); +} diff --git a/rust/traits.rs b/rust/traits.rs new file mode 100644 index 0000000..8f18c4e --- /dev/null +++ b/rust/traits.rs @@ -0,0 +1,27 @@ +trait HelloTrait { + fn hello(&self, s:String) -> String; +} + +struct HelloStruct { + name: String +} + +// Implementation of the trait for the struct +impl HelloTrait for HelloStruct { + fn hello(&self, s:String) -> String { + let x = format!("Hello {}, {}!", s, self.name); + x + } +} + +fn main() { + let example = HelloStruct { name: String::from("John") }; + println!("{}", example.hello(String::from("there"))); +} + +/* +Output: + +:!./traits +Hello there, John! + */