Thank you for watching the video and answering the question that I had from just reading the title.
Reversing a UTF-8 string is super hard in any language, rust doesn’t really make it that much harder.
Thank you for watching the video and answering the question that I had from just reading the title.
Reversing a UTF-8 string is super hard in any language, rust doesn’t really make it that much harder.
use std::collections::{BTreeSet, HashMap, HashSet};
use itertools::Itertools;
pub fn solve_part_1(input: &str) -> String {
let board: Vec<Vec<_>> = input.lines().map(|l| l.chars().collect()).collect();
let mut front: HashSet<_> = (0usize..board.len())
.cartesian_product(0usize..board[0].len())
.filter(|&(i, j)| board[i][j] == 'D')
.collect();
let mut visited = HashSet::new();
let knight_moves: [(isize, isize); 8] = [
(2, 1),
(2, -1),
(-2, -1),
(-2, 1),
(1, 2),
(1, -2),
(-1, -2),
(-1, 2),
];
for _ in 0..=4 {
let mut next_front = HashSet::new();
for (i, j) in front.drain() {
for (di, dj) in knight_moves {
let (ni, nj) = (i.wrapping_add_signed(di), j.wrapping_add_signed(dj));
if ni >= board.len() || nj >= board[0].len() {
continue;
}
if visited.contains(&(ni, nj)) {
continue;
}
next_front.insert((ni, nj));
}
visited.insert((i, j));
}
front = next_front;
}
visited
.drain()
.filter(|&(i, j)| board[i][j] == 'S')
.count()
.to_string()
}
fn solve_part_2_with_turns(input: &str, turns: usize) -> String {
let board: Vec<Vec<_>> = input.lines().map(|l| l.chars().collect()).collect();
let mut front: HashSet<_> = (0usize..board.len())
.cartesian_product(0usize..board[0].len())
.filter(|&(i, j)| board[i][j] == 'D')
.collect();
let knight_moves: [(isize, isize); 8] = [
(2, 1),
(2, -1),
(-2, -1),
(-2, 1),
(1, 2),
(1, -2),
(-1, -2),
(-1, 2),
];
let mut eaten_sheep = HashSet::new();
for turn in 0..=turns {
let mut next_front = HashSet::new();
for (i, j) in front.drain() {
for (di, dj) in knight_moves {
let (ni, nj) = (i.wrapping_add_signed(di), j.wrapping_add_signed(dj));
if ni >= board.len() || nj >= board[0].len() {
continue;
}
next_front.insert((ni, nj));
}
if board[i][j] != '#' {
if let Some(sheep_i) = (i + 1).checked_sub(turn)
&& board[sheep_i][j] == 'S'
{
eaten_sheep.insert((sheep_i, j));
}
if let Some(sheep_i) = i.checked_sub(turn)
&& turn != 0
&& board[sheep_i][j] == 'S'
{
eaten_sheep.insert((sheep_i, j));
}
}
}
front = next_front;
}
eaten_sheep.len().to_string()
}
pub fn solve_part_2(input: &str) -> String {
solve_part_2_with_turns(input, 20)
}
type VeryComplexType = HashMap<(usize, usize, usize, Vec<(usize, usize)>), usize>;
fn count_winning_sequences(
turn: usize,
dragon: (usize, usize),
hiding_places: &HashSet<(usize, usize)>,
sheep: BTreeSet<(usize, usize)>,
height: usize,
width: usize,
cache: &mut VeryComplexType,
) -> usize {
if sheep.is_empty() {
return 1;
}
let cache_key = (
turn % 2,
dragon.0,
dragon.1,
sheep.iter().cloned().collect(),
);
if let Some(result) = cache.get(&cache_key) {
return *result;
}
if turn % 2 == 1 {
let knight_moves: [(isize, isize); 8] = [
(2, 1),
(2, -1),
(-2, -1),
(-2, 1),
(1, 2),
(1, -2),
(-1, -2),
(-1, 2),
];
let (i, j) = dragon;
let mut total = 0;
for (di, dj) in knight_moves {
let (ni, nj) = (i.wrapping_add_signed(di), j.wrapping_add_signed(dj));
if ni >= height || nj >= width {
continue;
}
if !hiding_places.contains(&(ni, nj)) && sheep.contains(&(ni, nj)) {
let mut new_sheep = sheep.clone();
new_sheep.remove(&(ni, nj));
total += count_winning_sequences(
turn + 1,
(ni, nj),
hiding_places,
new_sheep,
height,
width,
cache,
);
} else {
total += count_winning_sequences(
turn + 1,
(ni, nj),
hiding_places,
sheep.clone(),
height,
width,
cache,
);
}
}
cache.insert(cache_key, total);
total
} else {
let mut sheep_moves_available = false;
let mut total = 0;
for &(i, j) in sheep.iter() {
if dragon == (i + 1, j) && !hiding_places.contains(&(i + 1, j)) {
continue;
}
sheep_moves_available = true;
if i == (height - 1) {
continue;
}
let mut new_sheep = sheep.clone();
new_sheep.remove(&(i, j));
new_sheep.insert((i + 1, j));
total += count_winning_sequences(
turn + 1,
dragon,
hiding_places,
new_sheep,
height,
width,
cache,
);
}
if !sheep_moves_available {
return count_winning_sequences(
turn + 1,
dragon,
hiding_places,
sheep,
height,
width,
cache,
);
}
cache.insert(cache_key, total);
total
}
}
pub fn solve_part_3(input: &str) -> String {
let board: Vec<Vec<_>> = input.lines().map(|l| l.chars().collect()).collect();
let dragon = (0usize..board.len())
.cartesian_product(0usize..board[0].len())
.filter(|&(i, j)| board[i][j] == 'D')
.exactly_one()
.unwrap();
let sheep = (0usize..board.len())
.cartesian_product(0usize..board[0].len())
.filter(|&(i, j)| board[i][j] == 'S')
.collect::<BTreeSet<_>>();
let hiding_places = (0usize..board.len())
.cartesian_product(0usize..board[0].len())
.filter(|&(i, j)| board[i][j] == '#')
.collect::<HashSet<_>>();
let mut cache = HashMap::new();
count_winning_sequences(
0,
dragon,
&hiding_places,
sheep,
board.len(),
board[0].len(),
&mut cache,
)
.to_string()
}
use std::collections::HashMap;
use bit_set::BitSet;
use itertools::{Itertools, izip};
type BitSetBase = u32;
fn is_child(child: &str, parent1: &str, parent2: &str) -> bool {
izip!(child.chars(), parent1.chars(), parent2.chars()).all(|(c, a, b)| c == a || c == b)
}
fn similarity(a: &str, b: &str) -> usize {
izip!(a.chars(), b.chars()).filter(|(a, b)| a == b).count()
}
fn unequality_bitset(a: &str, b: &str) -> BitSet<BitSetBase> {
izip!(a.chars(), b.chars())
.enumerate()
.filter_map(|(i, (a_ch, b_ch))| if a_ch == b_ch { None } else { Some(i) })
.collect()
}
pub fn solve_part_1(input: &str) -> String {
let dnas = input
.lines()
.map(|l| {
let (_, dna) = l.split_once(":").unwrap();
dna
})
.collect::<Vec<_>>();
let (child, parenta, parentb) = if is_child(dnas[0], dnas[1], dnas[2]) {
(dnas[0], dnas[1], dnas[2])
} else if is_child(dnas[1], dnas[0], dnas[2]) {
(dnas[1], dnas[0], dnas[2])
} else {
(dnas[2], dnas[0], dnas[1])
};
(similarity(child, parenta) * similarity(child, parentb)).to_string()
}
pub fn solve_part_2(input: &str) -> String {
let dnas = input
.lines()
.map(|l| {
let (_, dna) = l.split_once(":").unwrap();
dna
})
.collect::<Vec<_>>();
let unequalities = dnas
.iter()
.enumerate()
.cartesian_product(dnas.iter().enumerate())
.map(|((a_id, a), (b_id, b))| ((a_id, b_id), unequality_bitset(a, b)))
.collect::<HashMap<_, _>>();
let mut total_similarities = 0;
'outer: for (child_id, &child_string) in dnas.iter().enumerate() {
for (parent_a_id, &parent_a_string) in dnas.iter().enumerate() {
if parent_a_id == child_id {
continue;
}
for (parent_b_id, &parent_b_string) in dnas.iter().enumerate() {
if parent_b_id == child_id || parent_b_id == parent_a_id {
continue;
}
if unequalities[&(child_id, parent_a_id)]
.intersection(&unequalities[&(child_id, parent_b_id)])
.count()
== 0
{
total_similarities += similarity(child_string, parent_a_string)
* similarity(child_string, parent_b_string);
continue 'outer;
}
}
}
}
total_similarities.to_string()
}
pub fn solve_part_3(input: &str) -> String {
let dnas = input
.lines()
.map(|l| {
let (_, dna) = l.split_once(":").unwrap();
dna
})
.collect::<Vec<_>>();
let unequalities = dnas
.iter()
.enumerate()
.cartesian_product(dnas.iter().enumerate())
.map(|((a_id, a), (b_id, b))| ((a_id, b_id), unequality_bitset(a, b)))
.collect::<HashMap<_, _>>();
let mut parents: HashMap<usize, (usize, usize)> = HashMap::new();
'outer: for (child_id, _) in dnas.iter().enumerate() {
for (parent_a_id, _) in dnas.iter().enumerate() {
if parent_a_id == child_id {
continue;
}
for (parent_b_id, _) in dnas.iter().enumerate() {
if parent_b_id == child_id || parent_b_id == parent_a_id {
continue;
}
if unequalities[&(child_id, parent_a_id)]
.intersection(&unequalities[&(child_id, parent_b_id)])
.count()
== 0
{
parents.insert(child_id, (parent_a_id, parent_b_id));
continue 'outer;
}
}
}
}
let mut family_id = (0usize..dnas.len()).collect::<Vec<_>>();
for (child, (parent_a, parent_b)) in parents.drain() {
let destination_family_id = family_id[child];
let merge_families = (family_id[parent_a], family_id[parent_b]);
for candidate_family in family_id.iter_mut() {
if *candidate_family == merge_families.0 || *candidate_family == merge_families.1 {
*candidate_family = destination_family_id;
}
}
}
let families = family_id
.iter()
.enumerate()
.map(|(member_idx, &family_idx)| (family_idx, member_idx))
.into_group_map();
families
.values()
.max_by_key(|f| f.len())
.unwrap()
.iter()
.map(|member_id| member_id + 1)
.sum::<usize>()
.to_string()
}
I don't think there's such a thing as a "spirit of the question", but you're free to set your own challenges of course :)
ah, uiua, the only thing that makes me wish Unicode hadn't been invented :)
pub fn solve_part_1(input: &str) -> String {
let numbers: Vec<i32> = input.split(",").map(|x| x.parse().unwrap()).collect();
let mut count = 0;
for i in 1..numbers.len() {
if numbers[i].abs_diff(numbers[i - 1]) == 16 {
count += 1;
}
}
count.to_string()
}
pub fn solve_part_2(input: &str) -> String {
let numbers: Vec<i32> = input.split(",").map(|x| x.parse().unwrap()).collect();
let mut lines: Vec<(i32, i32)> = vec![];
for i in 1..numbers.len() {
let (a, b) = (numbers[i - 1], numbers[i]);
if a > b {
lines.push((b, a));
} else {
lines.push((a, b));
}
}
let mut knots = 0;
for i in 0..lines.len() {
for j in 0..i {
let (a, b) = lines[i];
let (c, d) = lines[j];
if a == c || a == d || b == c || b == d {
continue;
}
let c_inside = c > a && c < b;
let d_inside = d > a && d < b;
if c_inside != d_inside {
knots += 1;
}
}
}
knots.to_string()
}
pub fn solve_part_3(input: &str) -> String {
let numbers: Vec<i32> = input.split(",").map(|x| x.parse().unwrap()).collect();
let mut lines: Vec<(i32, i32)> = vec![];
for i in 1..numbers.len() {
let (a, b) = (numbers[i - 1], numbers[i]);
if a > b {
lines.push((b, a));
} else {
lines.push((a, b));
}
}
let mut best_cut_threads = i64::MIN;
for d in 1..=256 {
for c in 1..d {
let mut cut_threads = 0;
for (a, b) in lines.iter().copied() {
if a == c || a == d || b == c || b == d {
if a == c && b == d {
cut_threads += 1;
}
continue;
}
let c_inside = c > a && c < b;
let d_inside = d > a && d < b;
if c_inside != d_inside {
cut_threads += 1;
}
}
if cut_threads > best_cut_threads {
best_cut_threads = cut_threads;
}
}
}
best_cut_threads.to_string()
}
Technically you don't need to store the names in part 3, but I was too lazy.
use std::collections::{HashMap, HashSet};
pub fn solve_part_1(input: &str) -> String {
let (names, rules) = input.split_once("\n\n").unwrap();
let names: Vec<&str> = names.split(",").collect();
let rules: HashMap<char, HashSet<char>> = rules
.lines()
.map(|line| {
let (from, to) = line.split_once(" > ").unwrap();
let to = to.split(",");
(
from.chars().next().unwrap(),
to.map(|s| s.chars().next().unwrap()).collect(),
)
})
.collect();
for name in names {
let mut allowed_chars = rules.get(&name.chars().next().unwrap());
let mut acceptable = true;
for ch in name.chars().skip(1) {
match allowed_chars {
Some(allowed) => {
if !allowed.contains(&ch) {
acceptable = false;
break;
}
allowed_chars = rules.get(&ch);
}
None => {
panic!("no rules for letter {ch} in name {name}");
}
}
}
if acceptable {
return name.to_string();
}
}
panic!("all names bad");
}
pub fn solve_part_2(input: &str) -> String {
let (names, rules) = input.split_once("\n\n").unwrap();
let names: Vec<&str> = names.split(",").collect();
let rules: HashMap<char, HashSet<char>> = rules
.lines()
.map(|line| {
let (from, to) = line.split_once(" > ").unwrap();
let to = to.split(",");
(
from.chars().next().unwrap(),
to.map(|s| s.chars().next().unwrap()).collect(),
)
})
.collect();
let mut sum_of_indices = 0;
for (i, name) in names.into_iter().enumerate() {
let mut allowed_chars = rules.get(&name.chars().next().unwrap());
let mut acceptable = true;
for ch in name.chars().skip(1) {
match allowed_chars {
Some(allowed) => {
if !allowed.contains(&ch) {
acceptable = false;
break;
}
allowed_chars = rules.get(&ch);
}
None => {
panic!("no rules for letter {ch} in name {name}");
}
}
}
if acceptable {
sum_of_indices += 1 + i;
}
}
sum_of_indices.to_string()
}
fn gen_names_with_prefix(
prefix: &str,
rules: &HashMap<char, HashSet<char>>,
result: &mut HashSet<String>,
) {
if prefix.len() >= 7 {
result.insert(prefix.to_string());
}
if prefix.len() == 11 {
return;
}
let last_char = prefix.chars().last().unwrap();
if let Some(next_chars) = rules.get(&last_char) {
for next_char in next_chars {
let new_prefix = format!("{prefix}{next_char}");
gen_names_with_prefix(new_prefix.as_str(), rules, result);
}
}
}
pub fn solve_part_3(input: &str) -> String {
let (prefix, rules) = input.split_once("\n\n").unwrap();
let prefixes: Vec<_> = prefix.split(",").collect();
let rules: HashMap<char, HashSet<char>> = rules
.lines()
.map(|line| {
let (from, to) = line.split_once(" > ").unwrap();
let to = to.split(",");
(
from.chars().next().unwrap(),
to.map(|s| s.chars().next().unwrap()).collect(),
)
})
.collect();
let mut results: HashSet<String> = HashSet::new();
prefixes
.into_iter()
.filter(|&name| {
let mut allowed_chars = rules.get(&name.chars().next().unwrap());
let mut acceptable = true;
for ch in name.chars().skip(1) {
match allowed_chars {
Some(allowed) => {
if !allowed.contains(&ch) {
acceptable = false;
break;
}
allowed_chars = rules.get(&ch);
}
None => {
panic!("no rules for letter {ch} in name {name}");
}
}
}
acceptable
})
.for_each(|prefix| gen_names_with_prefix(prefix, &rules, &mut results));
results.len().to_string()
}
use std::collections::HashMap;
use itertools::Itertools;
pub fn solve_part_1(input: &str) -> String {
let mut mentors = 0;
let mut pairs = 0;
for ch in input.chars() {
match ch {
'A' => mentors += 1,
'a' => pairs += mentors,
_ => {}
}
}
pairs.to_string()
}
pub fn solve_part_2(input: &str) -> String {
let mut mentors: HashMap<char, i64> = HashMap::new();
let mut pairs = 0;
for ch in input.chars() {
match ch {
'A'..='Z' => *mentors.entry(ch).or_default() += 1,
'a'..='z' => pairs += *mentors.entry(ch.to_ascii_uppercase()).or_default(),
_ => panic!("unexpected character {ch}"),
}
}
pairs.to_string()
}
pub fn solve_part_3(input: &str) -> String {
let data: Vec<_> = input.chars().collect();
let len = data.len();
let mentors: HashMap<char, Vec<usize>> = data
.iter()
.enumerate()
.map(|(i, ch)| (*ch, i))
.into_group_map();
let mut pairs: i64 = 0;
for (squire_position, ch) in data.into_iter().enumerate() {
if ch.is_ascii_lowercase() {
for mentor_position in mentors.get(&ch.to_ascii_uppercase()).unwrap() {
if squire_position.abs_diff(*mentor_position) <= 1000 {
pairs += 1000;
} else if (squire_position as isize)
.wrapping_sub_unsigned(len)
.abs_diff(*mentor_position as isize)
<= 1000
|| (*mentor_position as isize)
.wrapping_sub_unsigned(len)
.abs_diff(squire_position as isize)
<= 1000
{
pairs += 999;
}
}
}
}
pairs.to_string()
}
use itertools::Itertools;
type Fishbone = Vec<(i64, Option<i64>, Option<i64>)>;
fn parse_fishbone(quality_str: &str) -> Fishbone {
let mut fishbone: Fishbone = vec![];
'outer: for num in quality_str.split(",").map(|x| x.parse().unwrap()) {
for e in fishbone.iter_mut() {
if num < e.0 && e.1.is_none() {
e.1 = Some(num);
continue 'outer;
}
if num > e.0 && e.2.is_none() {
e.2 = Some(num);
continue 'outer;
}
}
fishbone.push((num, None, None));
}
fishbone
}
fn compute_quality(fishbone: &Fishbone) -> i64 {
fishbone
.iter()
.map(|(c, _, _)| c.to_string())
.join("")
.parse()
.unwrap()
}
pub fn solve_part_1(input: &str) -> String {
let (_, data) = input.split_once(":").unwrap();
compute_quality(&parse_fishbone(data)).to_string()
}
pub fn solve_part_2(input: &str) -> String {
let mut worst_quality = i64::MAX;
let mut best_quality = i64::MIN;
for sword in input.lines() {
let (_, data) = sword.split_once(":").unwrap();
let quality = compute_quality(&parse_fishbone(data));
worst_quality = worst_quality.min(quality);
best_quality = best_quality.max(quality);
}
(best_quality - worst_quality).to_string()
}
pub fn solve_part_3(input: &str) -> String {
let mut swords: Vec<_> = input
.lines()
.map(|def| {
let (id, data) = def.split_once(":").unwrap();
let fishbone = parse_fishbone(data);
(id.parse::<i64>().unwrap(), fishbone)
})
.collect();
swords.sort_by(|a, b| {
let cmp = compute_quality(&a.1).cmp(&compute_quality(&b.1));
if !matches!(cmp, std::cmp::Ordering::Equal) {
return cmp;
}
for (a_seg, b_seg) in a.1.iter().zip(b.1.iter()) {
let a_val = match a_seg {
(a, Some(b), Some(c)) => format!("{b}{a}{c}"),
(a, Some(b), None) => format!("{b}{a}"),
(a, None, Some(c)) => format!("{a}{c}"),
(a, None, None) => format!("{a}"),
};
let b_val = match b_seg {
(a, Some(b), Some(c)) => format!("{b}{a}{c}"),
(a, Some(b), None) => format!("{b}{a}"),
(a, None, Some(c)) => format!("{a}{c}"),
(a, None, None) => format!("{a}"),
};
let cmp = a_val.parse::<i64>().unwrap().cmp(&b_val.parse().unwrap());
if !matches!(cmp, std::cmp::Ordering::Equal) {
return cmp;
}
}
a.0.cmp(&b.0)
});
swords.reverse();
swords
.into_iter()
.enumerate()
.map(|(pos, (id, _))| id * (pos as i64 + 1))
.sum::<i64>()
.to_string()
}
use num::{BigInt, Integer};
pub fn solve_part_1(input: &str) -> String {
let gears: Vec<i64> = input.trim().lines().map(|g| g.parse().unwrap()).collect();
(2025 * gears[0] / gears.last().unwrap()).to_string()
}
pub fn solve_part_2(input: &str) -> String {
let gears: Vec<i64> = input.trim().lines().map(|g| g.parse().unwrap()).collect();
let res = (BigInt::parse_bytes(b"10000000000000", 10).unwrap() * gears.last().unwrap())
.div_ceil(&(BigInt::ZERO + gears[0]));
res.to_string()
}
pub fn solve_part_3(input: &str) -> String {
let mut lines = input.trim().lines();
let first_gear = BigInt::parse_bytes(lines.next().unwrap().as_bytes(), 10).unwrap();
let mut nominator: BigInt = first_gear * 100;
let mut denominator: BigInt = BigInt::ZERO + 1;
for line in lines {
let mut split = line.split("|");
denominator *= BigInt::parse_bytes(split.next().unwrap().as_bytes(), 10).unwrap();
match split.next() {
Some(size) => {
nominator *= BigInt::parse_bytes(size.as_bytes(), 10).unwrap();
}
None => {
break;
}
}
}
(nominator / denominator).to_string()
}
pub fn solve_part_1(input: &str) -> String {
let mut crates: Vec<i64> = input.split(",").map(|s| s.parse().unwrap()).collect();
crates.sort();
let mut monotonic_subsequence = vec![crates[0]];
for size in crates.into_iter().skip(1) {
if size == *monotonic_subsequence.last().unwrap() {
continue;
}
monotonic_subsequence.push(size);
}
monotonic_subsequence.iter().sum::<i64>().to_string()
}
pub fn solve_part_2(input: &str) -> String {
let mut crates: Vec<i64> = input.split(",").map(|s| s.parse().unwrap()).collect();
crates.sort();
let mut monotonic_subsequence = vec![crates[0]];
for size in crates.into_iter().skip(1) {
if size == *monotonic_subsequence.last().unwrap() {
continue;
}
monotonic_subsequence.push(size);
if monotonic_subsequence.len() >= 20 {
break;
}
}
monotonic_subsequence.iter().sum::<i64>().to_string()
}
pub fn solve_part_3(input: &str) -> String {
let mut crates: Vec<i64> = input.split(",").map(|s| s.parse().unwrap()).collect();
crates.sort();
let mut monotonic_subsequences = vec![vec![crates[0]]];
for size in crates.into_iter().skip(1) {
let updateable_sequence = monotonic_subsequences
.iter_mut()
.find(|v| *v.last().unwrap() < size);
match updateable_sequence {
Some(v) => {
v.push(size);
}
None => {
monotonic_subsequences.push(vec![size]);
}
}
}
monotonic_subsequences.len().to_string()
}
use log::debug;
use std::collections::HashSet;
use regex::Regex;
#[derive(PartialEq, Eq, Hash, Clone)]
struct Number(isize, isize);
impl Number {
fn add(self: &Number, b: &Number) -> Number {
Number(self.0 + b.0, self.1 + b.1)
}
fn mul(self: &Number, b: &Number) -> Number {
Number(self.0 * b.0 - self.1 * b.1, self.0 * b.1 + self.1 * b.0)
}
fn div(self: &Number, b: &Number) -> Number {
Number(self.0 / b.0, self.1 / b.1)
}
}
pub fn solve_part_1(input: &str) -> String {
let re = Regex::new(r"A=\[(\d+),(\d+)\]").unwrap();
let (_, [x, y]) = re.captures(input).unwrap().extract();
let a = Number(x.parse().unwrap(), y.parse().unwrap());
let mut res = Number(0, 0);
for _ in 0..3 {
res = res.mul(&res);
res = res.div(&Number(10, 10));
res = res.add(&a);
}
format!("[{},{}]", res.0, res.1)
}
pub fn solve_part_2(input: &str) -> String {
let re = Regex::new(r"A=\[([-0-9]+),([-0-9]+)\]").unwrap();
let (_, [x, y]) = re.captures(input).unwrap().extract();
let a = Number(x.parse().unwrap(), y.parse().unwrap());
let mut engraved_points = 0;
let mut pts: HashSet<_> = HashSet::new();
for i in 0..=100 {
for j in 0..=100 {
let pt = Number(a.0 + 10 * i, a.1 + 10 * j);
let mut res = Number(0, 0);
engraved_points += 1;
pts.insert(pt.clone());
for _ in 0..100 {
res = res.mul(&res);
res = res.div(&Number(100_000, 100_000));
res = res.add(&pt);
if res.0.abs() > 1_000_000 || res.1.abs() > 1_000_000 {
engraved_points -= 1;
pts.remove(&pt);
break;
}
}
}
}
for i in 0..=100 {
debug!("{}", (0..=100).map(|j| if pts.contains(&Number(a.0 + 10*i, a.1 + 10*j)) { 'X' } else {'.'}).collect::<String>());
}
engraved_points.to_string()
}
pub fn solve_part_3(input: &str) -> String {
let re = Regex::new(r"A=\[([-0-9]+),([-0-9]+)\]").unwrap();
let (_, [x, y]) = re.captures(input).unwrap().extract();
let a = Number(x.parse().unwrap(), y.parse().unwrap());
let mut engraved_points = 0;
for i in 0..=1000 {
for j in 0..=1000 {
let pt = Number(a.0 + i, a.1 + j);
let mut res = Number(0, 0);
engraved_points += 1;
for _ in 0..100 {
res = res.mul(&res);
res = res.div(&Number(100_000, 100_000));
res = res.add(&pt);
if res.0.abs() > 1_000_000 || res.1.abs() > 1_000_000 {
engraved_points -= 1;
break;
}
}
}
}
engraved_points.to_string()
}
Just an ad article. "Did you also encounter skill issues while building web applications? Try my platform."
but how many COMEFROMs are there
imagine the diffs
Uninitialized automatic variables. E.g. (in C/C++):
cpp
int get_time() {
int time;
syscall(/* something that fails */, &time);
return time;
}
Rust seems to think panicking is better: https://github.com/rust-lang/rust/issues/115482
probably the worst option for a library
Even worse than returning garbage? :)
Interestingly, Rust is what brought me to this rabbit hole. It does indeed panic in now()[1], but the devs seem to be reluctant to provide the try_now() variant[2].
[1] https://doc.rust-lang.org/nightly/src/std/sys/pal/unix/time.rs.html#124 [2] https://github.com/rust-lang/rust/issues/115482
That chars() call hides a lot of complexity, but also even that might not be correct depending on what exactly you mean by “reversing a string”.