In part 2, I tried to only change the index while shuffling, but even with Rust and doing that its impossible to shuffle it some 15-digit number of times. Well, not impossible, but it will take 1000+ hours = 42+ days of continuous running and may even cause your computer to hang/freeze.
Can't see any other way to do it so seeing @jbristow
's spoilers and solution.
externcrateregex;externcrateutils;useregex::Regex;useutils::utils::read_input;// 119_315_717_514_047#[derive(Debug,Clone,Copy)]enumChange{Reverse,Cut(isize),Deal(usize),}fnparse_input(raw:String)->Vec<Change>{letREVERSE_RE:Regex=Regex::new(r"deal into new stack").unwrap();letCUT_RE:Regex=Regex::new(r"cut\s([-01234567890]+)").unwrap();letDEAL_RE:Regex=Regex::new(r"deal with increment\s([01234567890]+)").unwrap();raw.lines().map(|val|{ifREVERSE_RE.is_match(val){Change::Reverse}elseifCUT_RE.is_match(val){letcaps=CUT_RE.captures(val).unwrap();letnum=caps[1].parse::<isize>().unwrap();Change::Cut(num)}else{letcaps=DEAL_RE.captures(val).unwrap();letnum=caps[1].parse::<usize>().unwrap();Change::Deal(num)}}).collect()}fnshuffle_position(process:&Vec<Change>,cards_len:usize,mutcard_position:usize)->usize{forchangeinprocess{matchchange{Change::Reverse=>{card_position=cards_len-1-card_position;}Change::Cut(num)=>{ifnum>&0{letnum=*numasusize;ifnum<card_position{card_position-=num;}else{card_position=cards_len-(num-card_position);}}else{letnum=num.abs()asusize;ifnum<cards_len-card_position{card_position+=num}else{card_position=num-(cards_len-card_position);}}}Change::Deal(num)=>{card_position=(card_position*num)%cards_len;}}}card_position}fnpart_a(input:Vec<Change>)->usize{constcards_len:usize=10_007;letmutcards=(0_usize..cards_len).collect::<Vec<usize>>();forchangeininput{matchchange{Change::Reverse=>{cards.reverse();}Change::Cut(num)=>{ifnum>0{letnum=numasusize;letmutcut_cards:Vec<usize>=cards.drain(..num).collect();cards.append(&mutcut_cards);}else{letnum=num.abs()asusize;letmutcut_cards:Vec<usize>=cards.drain(cards.len()-num..).collect();cut_cards.append(&mutcards);cards=cut_cards;}}Change::Deal(num)=>{letmutnew_cards:Vec<usize>=[0_usize;cards_len].iter().map(|val|*val).collect();forindexin0..cards_len{new_cards[(index*num)%cards_len]=cards[index];}cards=new_cards;}}}forindexin0..cards_len{ifcards[index]==2019{returnindex;}}0_0}fnpart_b(shuffle:Vec<Change>)->usize{constcards_len:usize=119_315_717_514_047;constshuffle_times:usize=101_741_582_076_661;letmutcard_position:usize=2020;letmutcrazy:Vec<usize>=vec![];fortimein0..1_000_000{card_position=shuffle_position(&shuffle,cards_len,card_position);ifcrazy.contains(&card_position){println!("whoa {} | {}",card_position,time);}crazy.push(card_position);}card_position}fnmain(){letinput=read_input().unwrap();letprocessed_input=parse_input(input);println!("{:?}",part_a(processed_input));}
I take no shame in reading a few lisp solutions to spoil my answer. With every year, I find a new way of looking at data that uncovers new possible "cheats".
Just like my favorite solution to the sum of squares problem (the sum of the squares from 1 to n): m * (m + 1) * (2*m + 1) / 6
My solution in Rust
github : github.com/coolshaurya/advent_of_c...
In part 2, I tried to only change the index while shuffling, but even with Rust and doing that its impossible to shuffle it some 15-digit number of times. Well, not impossible, but it will take 1000+ hours = 42+ days of continuous running and may even cause your computer to hang/freeze.
Can't see any other way to do it so seeing @jbristow 's spoilers and solution.
I take no shame in reading a few lisp solutions to spoil my answer. With every year, I find a new way of looking at data that uncovers new possible "cheats".
Just like my favorite solution to the sum of squares problem (the sum of the squares from 1 to n):
m * (m + 1) * (2*m + 1) / 6
Didn't know about this equation. Also you may have accidentally written
m
instead ofn
in the formula :) .Whoops! The notes I have it in mark it as ‘partial sum(n2) for 1 to m = ...` (copied from wolfram alpha)