Skip to content

Commit

Permalink
Merge pull request #64 from dalurness/jesse/day-01-solution-2024
Browse files Browse the repository at this point in the history
Add my solutions to day 1 from this year and last
  • Loading branch information
dalurness authored Dec 2, 2024
2 parents 035475f + 6343a4e commit 191d2d5
Showing 1 changed file with 147 additions and 0 deletions.
147 changes: 147 additions & 0 deletions src/content/communitySolutions/01/janka102.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
descriptions: ["linux-x86-assembly", "gleam"]
---

## 2023

First solution in assembly. Linux only, sorry Windows users. It's not perfect, and I cheat a little bit by not formatting the output, but it works well enough.

To compile and run, use the following:

```sh
gcc day01.s -no-pie -o day01 && ./day01 | od -t u1
```

Note: Make sure you have the letters input named "input.txt" in the current directory.

```asm
.text
.global main
main:
# open file
movl $5, %eax
movl $path, %ebx
movl $0, %ecx
int $0x80
# read entire file
movl %eax, %ebx
movl $3, %eax
movl $buff, %ecx
movl $16384, %edx
int $0x80
movl %eax, len
movl $0, pos
main_loop:
call atoi
# check if less than 0, meaning end of file
cmp $0, %eax
jl end_loop
# increment the value at the country code position in the array
movl country_counts(, %eax, 1), %ebx
inc %ebx
movl %ebx, country_counts(, %eax, 1)
jmp main_loop
end_loop:
# write
movl $4, %eax
movl $1, %ebx
leal country_counts(, %ebx, 1), %ecx
movl $196, %edx
int $0x80
exit:
# exit
movl $1, %eax
movl $0, %ebx
int $0x80
# not really a good general purpose atoi, but it works here
.global atoi
atoi:
movl $0, %eax # eax will be the resulting integer
atoi_loop:
# check if at end of string
movl len, %ebx
movl pos, %ecx
cmpl %ebx, %ecx
jge atoi_end_pre
# read a char from the buffer and increment the read position
movl $0, %ebx
mov buff(, %ecx, 1), %bl
inc %ecx
movl %ecx, pos
# check if at a space
cmp $0x30, %bl
jl atoi_end
# actual conversion here.
# multiply previous result by 10 and add current
sub $0x30, %bl
movl $10, %ecx
mul %ecx
addl %ebx, %eax
jmp atoi_loop
atoi_end_pre:
movl $-1, %eax
atoi_end:
ret
.lcomm buff, 16384 # buffer for reading the file
.lcomm country_counts, 200 # array for accumulating the letter counts, 1 byte per country
.lcomm len, 4 # total length of the file
.lcomm pos, 4 # current position in the file
.data
path:
.string "./input.txt"
```

## 2024

First time using Gleam. I think there's room for improvement in my solution, but it's a start. I also see the similarity to elixir, but it's cool they have compile-to-js.

I didn't get file reading working at this time, so just copy/paste the contents of the file into the string.

```gleam
import gleam/io
import gleam/string
import gleam/dict
import gleam/list
import gleam/option.{Some, None}
import gleam/result
import gleam/pair
import gleam/int
pub fn main() {
// Copy/paste the contents of the file into the string here
let letters = "..."
let increment = fn(x) {
case x {
Some(i) -> i + 1
None -> 1
}
}
string.split(letters, on: " ")
|> list.map(fn(code) { result.unwrap(int.parse(code), or: -1) })
|> list.fold(dict.new(), fn(acc, code) { dict.upsert(acc, code, increment) })
|> dict.to_list()
|> list.sort(by: fn(e1, e2) { int.compare(pair.first(e1), pair.first(e2)) })
|> list.map(fn(e) { int.to_string(pair.first(e)) <> ": " <> int.to_string(pair.second(e)) })
|> string.join(with: "\n")
|> io.print()
}
```

One question I had while writing it: Why do I need to import `Some` and `None`? Loose experimenting shows I don't need to do that with `Ok` and `Error`.

0 comments on commit 191d2d5

Please sign in to comment.