Last active
January 1, 2024 16:36
-
-
Save pocarist/622a27fb8597b829b812f561ed3a9841 to your computer and use it in GitHub Desktop.
Answer: https://twitter.com/e869120/status/1741475801026204116# (rev.2)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://twitter.com/e869120/status/1741475801026204116# | |
(* | |
(20 + (((23 + 12) - 31) * ((20 * (24 + 1)) + 1))) | |
(((20 * 23) + (((12 + 31) - 20) * 24)) * (1 + 1)) | |
*) | |
let rec gcd a (b: int) = if b = 0 then a else gcd b (a % b) | |
let lcm a b = (a * b) / gcd a b | |
type Rational = | |
{ numerator: int | |
denominator: int } | |
static member Create(p, q) = | |
let p, q = | |
if q = 0 then | |
raise (System.DivideByZeroException()) | |
let g = gcd q p in | |
p / g, q / g | |
let p, q = if q > 0 then p, q else -p, -q | |
{ numerator = p; denominator = q } | |
static member (+)(m, n) = | |
Rational.Create(m.numerator * n.denominator + n.numerator * m.denominator, m.denominator * n.denominator) | |
static member (-)(m, n) = | |
Rational.Create(m.numerator * n.denominator - n.numerator * m.denominator, m.denominator * n.denominator) | |
static member (~-) m = | |
Rational.Create(-m.numerator, m.denominator) | |
static member ( * )(m, n) = | |
Rational.Create(m.numerator * n.numerator, m.denominator * n.denominator) | |
static member (/)(m, n) = | |
Rational.Create(m.numerator * n.denominator, m.denominator * n.numerator) | |
static member Abs(m) = | |
Rational.Create(abs m.numerator, m.denominator) | |
static member of_int n = Rational.Create(n, 1) | |
static member Zero = Rational.of_int 0 | |
static member One = Rational.of_int 1 | |
override this.ToString() = | |
if this.denominator = 1 then | |
this.numerator.ToString() | |
else | |
sprintf "[%A/%A]" this.numerator this.denominator | |
type t = | |
| Num of Rational | |
| Add of t * t | |
| Sub of t * t | |
| Mul of t * t | |
| Div of t * t | |
override this.ToString() = | |
match this with | |
| Num n -> n.ToString() | |
| Add(a, b) -> sprintf "(%s + %s)" (a.ToString()) (b.ToString()) | |
| Sub(a, b) -> sprintf "(%s - %s)" (a.ToString()) (b.ToString()) | |
| Mul(a, b) -> sprintf "(%s * %s)" (a.ToString()) (b.ToString()) | |
| Div(a, b) -> sprintf "(%s / %s)" (a.ToString()) (b.ToString()) | |
let rec eval = | |
function | |
| Num n -> Some n | |
| Add(a, b) -> | |
match eval b with | |
| None -> None | |
| x -> (eval a, x) ||> Option.map2 (+) | |
| Sub(a, b) -> | |
match eval b with | |
| None -> None | |
| x -> (eval a, x) ||> Option.map2 (-) | |
| Mul(a, b) -> | |
match eval b with | |
| None -> None | |
| x -> (eval a, x) ||> Option.map2 ( * ) | |
| Div(a, b) -> | |
match eval b with | |
| None -> None | |
| Some({ numerator = 0; denominator = _ }) -> None | |
| x -> (eval a, x) ||> Option.map2 (/) | |
let nums = [ 20; 23; 12; 31; 20; 24; 1; 1 ] | |
// let ops = [ Add; Sub; Mul; Div ] | |
let ops = [ Add; Sub; Mul ] | |
let solve target nums = | |
let target' = Rational.of_int target | |
let rec traverse stack nums = | |
let ans = | |
match stack, nums with | |
| x :: [], [] -> if eval x = Some target' then [ x ] else [] | |
| _, n :: ns -> | |
let expr = n |> Rational.of_int |> Num | |
traverse (expr :: stack) ns | |
| _ -> [] | |
match stack with | |
| x :: y :: zs -> | |
ops | |
|> List.fold | |
(fun acc op -> | |
let tmp = traverse (op (y, x) :: zs) nums | |
acc @ tmp) | |
ans | |
| _ -> ans | |
traverse [] nums | |
let rec normalize = function | |
| Num n -> Num n | |
| Add(a, Sub(b, c)) -> (Sub(Add(normalize a, normalize b), normalize c)) | |
| Add(a, b) -> Add(normalize a, normalize b) | |
| Sub(a, b) -> Sub(normalize a, normalize b) | |
| Mul(a, b) -> Mul(normalize a, normalize b) | |
| Div(a, b) -> Div(normalize a, normalize b) | |
let () = | |
let ans = solve 2024 nums | |
ans | |
|> List.map normalize | |
|> Set.ofList | |
|> Seq.map (fun x -> x.ToString()) | |
|> Seq.iter (printfn "%s") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment