advent of code day 1

DAY 0 DAY 2

main.s

.global _start
.section .text
_start:	
	movq (%rsp), %rax
	cmp $1, %rax
	jle _args_fail # fail if we have 1 or less args

	#open the file
	movq 16(%rsp), %rdi #filename
	xor %rsi, %rsi #flags
	xor %rdx, %rdx #mode
	movq $2, %rax #open syscall
	syscall	
	#save the fd 
	movq %rax, .input_file(%rip) 	
	
	#fstat get info about file
	movq %rax, %rdi #file descriptor
	movq $5, %rax #fstat syscall
	leaq .statbuf(%rip), %rsi #buffer to store the info
	syscall
	
	#map the file into memory
	movq $9, %rax #mmap syscall
	xor %rdi, %rdi 
	movq .statbuf+48(%rip), %rsi
	movq $7, %rdx
	movq $2, %r10
	movq .input_file(%rip), %r8
	movq $0, %r9
	syscall

	#save the pointer to the maped file.	
	movq %rax, .mmap_ptr(%rip)

	movq %rax, %rsi
	movq %rax, %r11 #current item address
	movq $0, %r14 #highest sum
	before:
	movq $0, %r12 #current sum
	movq %r11, %rsi
	call _get_elf_item_num
	cmp $0, %rax
	je _done 
	mov %rax, %r13 #item counter
	item_before: 
	movq %r11, %rsi
	call _get_item_as_int #also sets rdi to size of the item
	add %rax, %r12
	dec %r13
	add %rdi, %r11
	inc %r11
	cmp $0, %r13
	jne item_before
	_test_:
	cmp %r14, %r12
	jle _not_bigger
	movq %r12,%r14
	_not_bigger:
	inc %r11
	jmp before

		
	_done: 
	#printf("%d\n", %r14);	
	movq %r14, %rsi 
	leaq .printfmt(%rip), %rdi
	call printf@PLT
	
	#exit(0); 
	movq $60, %rax
	movq $0, %rdi
	syscall

_args_fail:
	leaq .args_message(%rip), %rdi
	call puts@PLT
	mov $1, %rdi
	mov $60, %rax
	syscall
_get_elf_item_num: #rsi(item_pointer)
	movq $0, %r9
	_name1:
	call _get_item_len
	cmp $0, %rax
	jne _not_eq
	mov %r9, %rax
	ret
	_not_eq:
	add %rax, %rsi
	inc %rsi
	inc %r9
	jmp _name1

_get_item_as_int: #rsi(item_pointer)
	call _get_item_len
	push %rax
	mov %rax, %r10
	mov %rsi, %r8
	mov $0, %r9
	dec %r8
	_gogotime:
	dec %r10
	inc %r8
	movq $10, %rdi
	movq %r10, %rsi
	call _exp
	movb (%r8), %dil
	sub $'0, %rdi
	imulq %rdi, %rax
	add %rax, %r9
	cmp $1, %r10
	jge _gogotime
	movq %r9, %rax
	pop %rdi
	ret
	

_get_item_len: #rsi(item_pointer)
	mov $0, %r10
	movq %rsi, %rax
	movq .mmap_ptr(%rip), %rdx
	add .statbuf+48(%rip), %rdx
	sub $1, %rax
	loop1: 
	inc %rax
	cmp %rdx, %rax #return if we have reached the end of the file
	je __ret1
	movb (%rax), %r10b
	cmp $'\n', %r10
	je __ret1 #if next char is not newline go back
	cmp $0, %r10
	jne loop1
	__ret1:
	sub %rsi, %rax
	ret 

_exp: #rdi^rsi
	cmp $0,%rsi
	je __is_zero
	mov %rdi, %rax
	_exp2:
	cmp $1, %rsi
	jle __ret2 
	imulq %rdi, %rax
	dec %rsi
	jmp _exp2
	__ret2:
	ret
	__is_zero:
	movq $1, %rax
	ret

.section .data
.args_message:
	.asciz "file name must be provided"
.printfmt:
	.asciz "%d\n"
.section .bss
.lcomm .elf_index 8
.lcomm .read_buf, 256
.lcomm .input_file, 8
.lcomm .statbuf, 144
.lcomm .mmap_ptr, 8

        

main.c

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

int main(int argc, char** argv){
	if(argc != 2){
		fprintf(stderr, "You must provide 1 argument (filename)");
		return -1;
	}
	
	FILE* fp = fopen(argv[1],"r");

	int max_elf_cals = 0;
	
	char* line=NULL;
	size_t length=0;

	while(1){
		int current_elf_cals = 0;
		while(1){
			if (getline(&line,&length,fp) == -1)
				goto end;
			if (line==NULL)
				goto end;
			if(*line=='\n')
				break;
			current_elf_cals += atoi(line);
			free(line);
			line=NULL;			
		}
		if(current_elf_cals > max_elf_cals)
			max_elf_cals = current_elf_cals;
		continue;

		end:
		if(line)
			free(line);
		if(current_elf_cals > max_elf_cals)
			 max_elf_cals =  current_elf_cals;
		break;
	}
		
	printf("%d",max_elf_cals);
	return 0;
}

        

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 cur_sum = 0;
    let mut max_sum = 0;
    for line in f_cont.split("\n"){
        if line == "" {
            if cur_sum > max_sum {
                max_sum = cur_sum;
            }
            cur_sum = 0;
            continue;
        }
        cur_sum += line.parse::<i32>().unwrap();
    }
    println!("{}",max_sum);
}

        

main.rb

#!/usr/bin/ruby
cur_sum=0
max_sum=0

File.foreach(ARGV[0]) { |line|
  cur_sum = 0 
  if line == "\n"
    if cur_sum>max_sum
      max_sum=cur_sum
    end
    cur_sum=0
  else
    cur_sum+=Integer(line)
  end
}

puts max_sum

        

main.py

#! /usr/bin/env python3

import sys



content = open(sys.argv[1]).read().split("\n")

split_list = []
temp_list = []
for i in content:
    if(i == ""):
        split_list.append(temp_list)
        temp_list = []
    else:
        temp_list.append(i)

max_sum = 0
for i in split_list:
    cur_sum = 0
    for j in i:
        cur_sum+=int(j)
    if(cur_sum > max_sum):
        max_sum=cur_sum

print(max_sum)

        

main.hs

import System.IO 
import System.Environment 
import Control.Monad
import Data.List.Split

main = do
        args <- getArgs
        handle <- openFile (args !! 0) ReadMode
        contents <- hGetContents handle  
        print $ maximum $ map listSum $ splitOn [""] $ lines contents
        hClose handle   

listSum :: [String] -> Int
listSum x = sum $ slToIl x

slToIl :: [String] -> [Int]
slToIl = map read

        

times.txt

time it took for each program to run on a ~500mb file ~90M lines
main.s:  2.818s 
main.c:  6.151s 
main.rs: 17.665s
main.rb: 41.928 
main.py: 57.642s
main.hs: 4m0.190s (used 20gb of ram) 


        

DAY 0 DAY 2