day02
This commit is contained in:
		
							parent
							
								
									da179bdc15
								
							
						
					
					
						commit
						ace0f38373
					
				
					 5 changed files with 135 additions and 0 deletions
				
			
		
							
								
								
									
										4
									
								
								2024/day02/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								2024/day02/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
*.beam
 | 
			
		||||
*.ez
 | 
			
		||||
/build
 | 
			
		||||
erl_crash.dump
 | 
			
		||||
							
								
								
									
										20
									
								
								2024/day02/gleam.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								2024/day02/gleam.toml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
name = "day02"
 | 
			
		||||
version = "1.0.0"
 | 
			
		||||
 | 
			
		||||
# Fill out these fields if you intend to generate HTML documentation or publish
 | 
			
		||||
# your project to the Hex package manager.
 | 
			
		||||
#
 | 
			
		||||
# description = ""
 | 
			
		||||
# licences = ["Apache-2.0"]
 | 
			
		||||
# repository = { type = "github", user = "", repo = "" }
 | 
			
		||||
# links = [{ title = "Website", href = "" }]
 | 
			
		||||
#
 | 
			
		||||
# For a full reference of all the available options, you can have a look at
 | 
			
		||||
# https://gleam.run/writing-gleam/gleam-toml/.
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
 | 
			
		||||
gleam_yielder = ">= 1.1.0 and < 2.0.0"
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
gleeunit = ">= 1.0.0 and < 2.0.0"
 | 
			
		||||
							
								
								
									
										13
									
								
								2024/day02/manifest.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								2024/day02/manifest.toml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
# This file was generated by Gleam
 | 
			
		||||
# You typically do not need to edit this file
 | 
			
		||||
 | 
			
		||||
packages = [
 | 
			
		||||
  { name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" },
 | 
			
		||||
  { name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
 | 
			
		||||
  { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[requirements]
 | 
			
		||||
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
 | 
			
		||||
gleam_yielder = { version = ">= 1.1.0 and < 2.0.0" }
 | 
			
		||||
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
 | 
			
		||||
							
								
								
									
										74
									
								
								2024/day02/src/day02.gleam
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								2024/day02/src/day02.gleam
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
import gleam/bool
 | 
			
		||||
import gleam/int
 | 
			
		||||
import gleam/io
 | 
			
		||||
import gleam/list
 | 
			
		||||
import gleam/result
 | 
			
		||||
import gleam/string
 | 
			
		||||
import gleam/yielder
 | 
			
		||||
import stdin.{stdin}
 | 
			
		||||
 | 
			
		||||
pub fn main() {
 | 
			
		||||
  let reports =
 | 
			
		||||
    stdin()
 | 
			
		||||
    |> yielder.map(fn(line) {
 | 
			
		||||
      let assert #(ints, []) =
 | 
			
		||||
        string.trim_end(line)
 | 
			
		||||
        |> string.split(" ")
 | 
			
		||||
        |> list.map(int.parse)
 | 
			
		||||
        |> result.partition
 | 
			
		||||
      ints
 | 
			
		||||
    })
 | 
			
		||||
    |> yielder.to_list
 | 
			
		||||
 | 
			
		||||
  part1(reports)
 | 
			
		||||
  |> int.to_string
 | 
			
		||||
  |> io.println
 | 
			
		||||
 | 
			
		||||
  part2(reports)
 | 
			
		||||
  |> int.to_string
 | 
			
		||||
  |> io.println
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn part1(reports: List(List(Int))) -> Int {
 | 
			
		||||
  list.map(reports, is_safe)
 | 
			
		||||
  |> list.count(fn(x) { x })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn part2(reports: List(List(Int))) {
 | 
			
		||||
  let #(safe, unsafe) = list.partition(reports, is_safe)
 | 
			
		||||
  let non_unsafe =
 | 
			
		||||
    list.map(unsafe, fn(report) {
 | 
			
		||||
      list.combinations(report, list.length(report) - 1)
 | 
			
		||||
      |> until_true(is_safe)
 | 
			
		||||
    })
 | 
			
		||||
  list.length(safe) + list.count(non_unsafe, fn(x) { x })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn until_true(over list: List(a), with fun: fn(a) -> Bool) -> Bool {
 | 
			
		||||
  case list {
 | 
			
		||||
    [] -> False
 | 
			
		||||
    [head] -> fun(head)
 | 
			
		||||
    [head, ..tail] ->
 | 
			
		||||
      case fun(head) {
 | 
			
		||||
        True -> True
 | 
			
		||||
        False -> until_true(tail, fun)
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn is_safe(report: List(Int)) -> Bool {
 | 
			
		||||
  list.window_by_2(report)
 | 
			
		||||
  |> list.try_fold(0, fn(sum, window) {
 | 
			
		||||
    let diff = window.1 - window.0
 | 
			
		||||
    case int.absolute_value(diff) {
 | 
			
		||||
      x if x >= 1 && x <= 3 ->
 | 
			
		||||
        case bool.exclusive_nor(sum > 0, diff > 0) {
 | 
			
		||||
          True -> Ok(sum + diff)
 | 
			
		||||
          False if sum == 0 -> Ok(sum + diff)
 | 
			
		||||
          False -> Error(Nil)
 | 
			
		||||
        }
 | 
			
		||||
      _ -> Error(Nil)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  |> result.is_ok
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								2024/day02/src/stdin.gleam
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								2024/day02/src/stdin.gleam
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
import gleam/dynamic
 | 
			
		||||
import gleam/result
 | 
			
		||||
import gleam/yielder
 | 
			
		||||
 | 
			
		||||
@external(erlang, "io", "get_line")
 | 
			
		||||
fn ffi_read_line(prompt: String) -> dynamic.Dynamic
 | 
			
		||||
 | 
			
		||||
fn read_line() -> Result(String, Nil) {
 | 
			
		||||
  ffi_read_line("")
 | 
			
		||||
  |> dynamic.from()
 | 
			
		||||
  |> dynamic.string()
 | 
			
		||||
  |> result.replace_error(Nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn assert_upwrap(res: Result(a, _)) -> a {
 | 
			
		||||
  let assert Ok(a) = res
 | 
			
		||||
  a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn stdin() -> yielder.Yielder(String) {
 | 
			
		||||
  yielder.repeatedly(read_line)
 | 
			
		||||
  |> yielder.take_while(result.is_ok)
 | 
			
		||||
  |> yielder.map(assert_upwrap)
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue