advent of code day 3

DAY 2 DAY 4

main.s

.global _start
.section .text
_start:
	movq (%rsp), %rax
	cmp $1, %rax
	jle _args_fail
	
	movq $2, %rax #open
	xor %rsi, %rsi #flags 0 is readonly
	xor %rsi, %rsi #mode only used when creating files	
	movq 16(%rsp), %rdi #args[1]
	syscall
	movq %rax, %r15 #fd
	
	movq $5, %rax #fstat
	movq %r15, %rdi
	leaq .statbuf(%rip), %rsi 
	syscall
	
	movq $9, %rax                #mmap to map file to memory
	xor %rdi, %rdi               #addr, not used here
	movq .statbuf+48(%rip), %rsi #length of the allocation (size of file)
	movq $7, %rdx                #permissions read/write/exec
	movq $2, %r10                #map_private (don't save changes to the file)
	movq %r15, %r8		     #fd
	movq $0, %r9 		     #offset 	
	syscall
	mov %rax, %r15 #current point in alloc
	sub $1, %r15
	mov %rax, %r14
	add .statbuf+48(%rip), %r14 #enf of alloc
	mov $0, %rax #clear the register 
	movq $0, %r10 # the total score
_start_of_comp1:
	inc %r15
	call _get_line_length
	movq %rax, %rdx
	shr $1, %rdx
	call _clear_sackbuf
	leaq .rucksackbuf-1(%rip), %rsi
_start_of_char1:
	cmp %r15, %r14 #if(eof) 
	je _end 
	movb (%r15), %al
	movb %al, %r9b
	dec %rdx
	inc %r15
	call _get_priority
	movq %rsi, %rdi #load suckbuf-1 addr 
	add %rax, %rdi # get to the correct index
	movb $'A, (%rdi) # set to present
	cmp $0, %rdx
	je _start_of_comp2
	jmp _start_of_char1
_start_of_comp2:
	cmp %r15, %r14
	je _end
	movb (%r15), %al
	cmp $'\n, %al
	je _start_of_comp1
	inc %r15
	call _get_priority
	movq %rsi, %rdi
	add %rax, %rdi
	cmpb $0, (%rdi)
	je _start_of_comp2
_found_match:	
	add %rax, %r10
	cmp %r15, %r14
	je _end
_goto_line_end:
	movb (%r15), %al
	cmp $'\n, %al	
	je _start_of_comp1
	inc %r15
	jmp _goto_line_end
_end:
	movq %r10, %rsi
	leaq .printfmt(%rip), %rdi
	call printf@PLT
		
	movq $60, %rax
	movq $0, %rdi
	syscall
	

_get_line_length:
	movq %r15, %rdi
	movq $0, %rax
_loop_start:
	cmp %rdi, %r14
	je _loop_end
	movb (%rdi), %sil
	cmp $'\n, %sil
	je _loop_end
	inc %rax
	inc %rdi
	jmp _loop_start	
_loop_end:
	ret

_get_priority: #replace the value in %al with the priority of the item
	sub $38, %al #correct priority for capital letters
	cmp $53, %al
	jge _lowercase
	ret
_lowercase:
	sub $58, %al
	ret

_clear_sackbuf: 
	#push %rax
	#push %rsi
	#push %rdi
	
	movq $0, .rucksackbuf(%rip)
	movq $0, .rucksackbuf+8(%rip)
	movq $0, .rucksackbuf+16(%rip)
	movq $0, .rucksackbuf+24(%rip)
	movq $0, .rucksackbuf+32(%rip)
	movq $0, .rucksackbuf+40(%rip)
	movl $0, .rucksackbuf+48(%rip)

	#pop %rdi
	#pop %rsi
	#pop $rax	
	ret

_args_fail:
	leaq .args_fail_message(%rip), %rdi
	call puts@PLT
	movq $60, %rax
	movq $1, %rdi
	syscall
.section .data
.args_fail_message:
	.asciz "you must provide a filename"	
.printfmt:
	.asciz "%d\n"

.section .bss
.lcomm	.statbuf 144
.lcomm  .rucksackbuf 52 

        

main.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

int getpri(char c){
	c -= 38;
	if(c > 52)
		c-=58;
	return c;
}

int main(int argc, char** argv) {
	if(argc != 2){
		fprintf(stderr, "you must give filename plz");
		return 1;
	}
	
	FILE* fp = fopen(argv[1], "r");
	int total_score = 0;

	char* line;
	size_t line_len;
	char primap[52];
	
	int ln=0;	

	while(1) {
		memset(primap,0,52);
		if(getline(&line,&line_len,fp) == -1)
			break;
		ln++;
		if(line==NULL)
			break;
		if(*line=='\n')
			break;
		if(*line==0)
			break;
		line_len = strlen(line);
		if(line_len %2 == 1){
			line_len--;
			line[line_len]=0;
		}
		for(int i=0;i<line_len/2;i++)
			primap[getpri(line[i])-1] = 1;
		for(int i=line_len/2;i<line_len;i++) { 
			if (primap[getpri(line[i])-1]){
				total_score+=getpri(line[i]);
				goto eol;
			}
		}
		eol:
		if(line)
			free(line);
		line=0;
	}	
	printf("%d\b", total_score);
}

        

main.py

#!/usr/bin/env python3
import sys
import re
lines = open(sys.argv[1]).read().split("\n")

total_score = 0

for line in lines[0:-1]:
    first_half = line[:len(line)//2]
    second_half = line[len(line)//2:]

    doublechar = list(set(first_half)  & set(second_half))[0] 

    pri = ord(doublechar) - 38
    if pri > 52:
        pri -= 58

    total_score+=pri
print(total_score)

        

main.rs

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

fn get_intersection (first: &[u8], second: &[u8]) -> u8{
   for i in first{
       for j in second {
           if *i == *j{
               return *i;
           }
       }
   }
   return 0;
}

fn main(){
    let f_cont = fs::read_to_string(env::args().nth(1).unwrap()).expect("no file");
    let f_cont = f_cont.split("\n");

    let mut total_score:u64 =0;

    for line in f_cont{ 
        if line.len() == 0 {
            continue;
        }
        let line = line.as_bytes();
        let (first, second) = line.split_at(line.len()/2);
        let doublechar = get_intersection(first,second);  

        if doublechar < 91{
            total_score += doublechar as u64 - 38;
        } else{
            total_score += doublechar as u64 - 96;
        }
        

    }
    println!("{}",total_score);

}


        

main.rb

#!/usr/bin/ruby


def get_priority(x)
  if x.ord < 91
    return x.ord - 38
  else
    return x.ord - 96
  end
end


total_score = 0

File.foreach(ARGV[0]) { |line|
  line=line.chars 
  spl = line.each_slice(line.size / 2).to_a
  spl = spl[0] & spl[1]
  total_score+=get_priority spl[0]  
}

puts total_score

        

main.hs

import System.IO
import System.Environment

import Data.Char (ord)

main = do
	args <- getArgs
	handle <- openFile(args !! 0) ReadMode
	contents <- hGetContents handle
	let half_lists = map halfList $ lines contents
	print $ sum $ map getPriority $ map intersect half_lists

getLineScore :: String -> Int
getLineScore s = 5 

halfList :: [a] -> ([a],[a])
halfList x = splitAt(length x `div` 2) x

intersect :: Eq a => ([a], [a]) -> a
intersect (l1, l2) = (filter (\n -> n `elem` l1) l2) !! 0

getPriority :: Char -> Int
getPriority x =  
	if ord x < 91 then ord x - 38
	else ord x - 96
	
		  

        

times.txt

time it took each program to run on a ~500mb file, 5 million lines
main.s: 2.235s       line length: O(n)   number of lines: O(n) 
main.c: 4.410s       line length: O(n)   number of lines: O(n) 
main.py: 22.920s     line length: O(n)   number of lines: O(n) 
main.rs: 49.507s     line length: O(n^2) number of lines: O(n)
main.rb: 1m58.724s   line length: O(n^2) number of lines: O(n)
main.hs: 2m11.189    i don't know, but it used 22 gb of ram

        

DAY 2 DAY 4