advent of code day 2

DAY 1 DAY 3

main.s

.global _start
.section .text
_start:
	movq (%rsp), %rax
	cmp $1, %rax
	jle _args_fail

	#open
	movq $2, %rax #open	
	movq 16(%rsp), %rdi #fname
	xor %rsi, %rsi #flags 0 is rdonly
	xor %rsi, %rsi #mode used when creating a new file
	syscall
	
	//store fd in r15
	movq %rax, %r15
	
	#fstat for size
	movq $5, %rax #fstat
	movq %r15, %rdi #fd 
	leaq .statbuf(%rip), %rsi #statbuf
	syscall
	
	#mmap	
	movq $9, %rax
	xor %rdi, %rdi # addr(?)
	movq .statbuf+48(%rip), %rsi #length
	movq $7, %rdx # read/write/exec permissions
	movq $2, %r10 # map_private will not change underlying file
	movq %r15, %r8 #fd 
	movq $0, %r9
	syscall
	movq %rax, %r14
	
	movq %rax, %r13 #addr of end
	addq .statbuf+48(%rip), %r13 
	sub $3, %r13 #only continue if there are 3 more chars in the file	

	movq $0, %r15 #total score
	movq $0, %rax
	movq $0, %rbx
	_start_of_round:
	movb (%r14), %al
	subb $64, %al # 'A' - 64 = 1
	add %rax, %r15 # add score
	add  $2, %r14 # goto op move
	movb (%r14), %bl
	subb $87, %bl
	subb %al, %bl
	cmp $0, %bl
	je _draw
	cmp $1, %bl
	je _lose
	cmp $-2, %bl
	je _lose
	#subq
	_win:
		add $3, %r15
	_draw:
		add $3, %r15
	_lose:
	add $2, %r14
	cmp %r14, %r13
	jg _start_of_round 
	
	leaq .printfmt(%rip), %rdi
	movq %r15, %rsi
	call printf@PLT

	movq $60, %rax 
	movq $0, %rdi
	syscall
	
_args_fail:
	leaq .args_fail_msg(%rip), %rdi
	call puts@PLT
	movq $60, %rax
	movq $1, %rdi
	syscall
	
.section .data
.args_fail_msg:
	.asciz "file name must be provided"
.printfmt:
	.asciz "%d\n"
.section .bss
.lcomm .statbuf 144

        

main.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/mman.h>
#include<fcntl.h>


int main(int argc, char** argv){
	if(argc < 2){
		printf("you must provide a filename\n");
		return 1;
	}
	
	int fd = open(argv[1], O_RDONLY, 0);
	struct stat* statbuf = (struct stat*) malloc(sizeof(struct stat));
	fstat(fd,statbuf);
	char* filebuf = (char*) mmap(0,statbuf->st_size + 1,PROT_READ | PROT_WRITE,MAP_PRIVATE,fd,0);
	filebuf[statbuf->st_size] = 0; //for debug
	

	int total_score = 0;
	char* fbuf_end = filebuf + statbuf->st_size;
	while(filebuf + 4 <= fbuf_end){
		int my_move = filebuf[0] - 64;
		total_score+=my_move;
		int opp_move = filebuf[2] - 87;
		int s = opp_move-my_move;
		if(s == 0)
			total_score+=3;
		if(s == -1 || s == 2)
			total_score+=6;
		
		filebuf+=4; //"A B\n"
	}

	printf("%d", total_score);

	free(statbuf);
	munmap(filebuf,statbuf->st_size+1);
}


        

main.rs

use std::fs;
use std::env;

fn main(){
    let f_cont = fs::read_to_string(env::args().nth(1).unwrap()).expect("no file");
    
    let mut total_score: u64 = 0;
    for line in f_cont.split("\n"){
        let s = line.as_bytes();
        if s.len() < 3 { continue; }
        
        let my_move = s[0] - 64;
        total_score+=my_move as u64;

        let op_move = s[2] - 87;
        let result: i16 = op_move as i16 - my_move as i16;
        
        if result == 0 {
            total_score+=3;
        }
        
        if result == -1 || result == 2 {
            total_score+=6;
        }
    } 
    println!("{}", total_score);

}


        

main.py

#!/usr/bin/env python3
import sys

match = {
        "A X": 3, "A Y": 0, "A Z": 6,
        "B X": 6, "B Y": 3, "B Z": 0,
        "C X": 0, "C Y": 6, "C Z": 3
}

base={
    "A": 1, "B": 2, "C": 3
}

if(len(sys.argv) < 2):
    print("you must provide an agument")
    exit()

lines = [i for i in open(sys.argv[1]).read().split("\n") if i in match]
total_score = 0

for line in lines:
    total_score+=match[line] + base[line[0:1]]    
print(total_score)

        

main.rb

#!/usr/bin/ruby
match = {
  "A X" => 3, "A Y" => 0, "A Z" => 6,
  "B X" => 6, "B Y" => 3, "B Z" => 0,
  "C X" => 0, "C Y" => 6, "C Z" => 3
}

base ={
  "A" => 1, "B" => 2, "C" => 3
}

total_score = 0
File.foreach(ARGV[0]) { |line|
  if not match.key?(line.chomp)
    next
  end
  total_score+= base[line[0,1]] + match[line.chomp]
}
puts total_score

        

main.hs

import Data.Map
import System.Environment
import System.IO


matchMap = Data.Map.fromList([
	("A X", 3), ("A Y", 0), ("A Z", 6),
	("B X", 6), ("B Y", 3), ("B Z", 0),
	("C X", 0), ("C Y", 6), ("C Z", 3)])

moveMap = Data.Map.fromList([("A", 1), ("B", 2), ("C", 3)])

main = do
	args <- getArgs
	handle <- openFile(args !! 0) ReadMode
	contents <- hGetContents handle
	print $ totalScore $ lines contents
	hClose handle

totalScore :: [String] -> Int
totalScore x = sum $ Prelude.map roundScore x	

roundScore :: String -> Int
roundScore s =  if length s /= 0 
	then findWithDefault 0 [(s !! 0)]  moveMap + findWithDefault 0 s matchMap
	else 0 


        

times.txt

time it took for each program to run on a ~400mb file 100M lines
main.s: 0.832s 
main.c: 1.587s
main.rs: 13.177s 
main.py: 40.642s
main.rb: 1m43.046s 
main.hs: 2m6.875s (used 22GB of ram) 

        

DAY 1 DAY 3