Rep-string

#include <stdio.h>
#include <string.h>

int repstr(char *str)
{
    if (!str) return 0;

    size_t sl = strlen(str) / 2;
    while (sl > 0) {
        if (strstr(str, str + sl) == str)
            return sl;
        --sl;
    }

    return 0;
}

int main(void)
{
    char *strs[] = { "1001110011", "1110111011", "0010010010", "1111111111",
        "0100101101", "0100100", "101", "11", "00", "1" };

    size_t strslen = sizeof(strs) / sizeof(strs[0]);
    size_t i;
    for (i = 0; i < strslen; ++i) {
        int n = repstr(strs[i]);
        if (n)
            printf("\"%s\" = rep-string \"%.*s\"\n", strs[i], n, strs[i]);
        else
            printf("\"%s\" = not a rep-string\n", strs[i]);
    }

    return 0;
}

fn main() {
    let strings = vec![
        String::from("1001110011"),
        String::from("1110111011"),
        String::from("0010010010"),
        String::from("1010101010"),
        String::from("1111111111"),
        String::from("0100101101"),
        String::from("0100100"),
        String::from("101"),
        String::from("11"),
        String::from("00"),
        String::from("1"),
    ];
    for string in strings {
        match rep_string(&string) {
            Some(rep_string) => println!(
                "Longuest rep-string for '{}' is '{}' ({} chars)",
                string,
                rep_string,
                rep_string.len(),
            ),
            None => println!("No rep-string found for '{}'", string),
        };
    }
}

fn rep_string(string: &str) -> Option<&str> {
    let index = string.len() / 2;

    for split_index in (1..=index).rev() {
        let mut is_rep_string = true;
        let (first, last) = string.split_at(split_index);

        let inter = last.chars().collect::<Vec<char>>();
        let mut iter = inter.chunks_exact(split_index);
        for chunk in iter.by_ref() {
            if first != chunk.iter().collect::<String>() {
                is_rep_string = false;
                break;
            }
        }
        let rmnd = iter.remainder().iter().collect::<String>();

        if !first.starts_with(rmnd.as_str()) {
            is_rep_string = false;
        }

        if is_rep_string {
            return Some(first);
        }
    }
    None
}

#[cfg(test)]
mod tests {
    use super::rep_string;
    use std::collections::HashMap;

    #[test]
    fn test_rep_string() {
        let mut results = HashMap::new();
        results.insert(String::from("1001110011"), Some("10011"));
        results.insert(String::from("1110111011"), Some("1110"));
        results.insert(String::from("0010010010"), Some("001"));
        results.insert(String::from("1010101010"), Some("1010"));
        results.insert(String::from("1111111111"), Some("11111"));
        results.insert(String::from("0100101101"), None);
        results.insert(String::from("0100100"), Some("010"));
        results.insert(String::from("101"), None);
        results.insert(String::from("11"), Some("1"));
        results.insert(String::from("00"), Some("0"));
        results.insert(String::from("1"), None);

        for (input, expected) in results {
            assert_eq!(expected, rep_string(&input));
        }
    }
}


Return multiple values

#include<stdio.h>

typedef struct{
	int integer;
	float decimal;
	char letter;
	char string[100];
	double bigDecimal;
}Composite;

Composite example()
{
	Composite C = {1, 2.3, 'a', "Hello World", 45.678};
	return C;
}

int main()
{
	Composite C = example();

	printf("Values from a function returning a structure : { %d, %f, %c, %s, %f}\n", C.integer, C.decimal, C.letter, C.string, C.bigDecimal);

	return 0;
}

fn multi_hello() -> (&'static str, i32) {
    ("Hello",42)
}

fn main() {
    let (str,num)=multi_hello();
    println!("{},{}",str,num);
}


Rock-paper-scissors

#include <stdio.h>
#include <stdlib.h>
#define LEN 3

int rand_idx(double *p, int n)
{
	double s = rand() / (RAND_MAX + 1.0);
	int i;
	for (i = 0; i < n - 1 && (s -= p[i]) >= 0; i++);
	return i;
}

int main()
{
	int user_action, my_action;
	int user_rec[] = {0, 0, 0};
	const char *names[] = { "Rock", "Paper", "Scissors" };
	char str[2];
	const char *winner[] = { "We tied.", "Meself winned.", "You win." };
	double  p[LEN] = { 1./3, 1./3, 1./3 };

	while (1) {
		my_action = rand_idx(p,LEN);

		printf("\nYour choice [1-3]:\n"
			"  1. Rock\n  2. Paper\n  3. Scissors\n> ");

		if (!scanf("%d", &user_action)) {
			scanf("%1s", str);
			if (*str == 'q') {
				printf("Your choices [rock : %d , paper :  %d , scissors %d] ",user_rec[0],user_rec[1], user_rec[2]);
				return 0;
			}
			continue;
		}
		user_action --;
		if (user_action > 2 || user_action < 0) {
			printf("invalid choice; again\n");
			continue;
		}
		printf("You chose %s; I chose %s. %s\n",
			names[user_action], names[my_action],
			winner[(my_action - user_action + 3) % 3]);

		user_rec[user_action]++;
	}
}

extern crate rand;
#[macro_use]
extern crate rand_derive;

use std::io;
use rand::Rng;
use Choice::*;

#[derive(PartialEq, Clone, Copy, Rand, Debug)]
enum Choice {
    Rock,
    Paper,
    Scissors,
}

fn beats(c1: Choice, c2: Choice) -> bool {
    (c1 == Rock && c2 == Scissors) || (c1 == Scissors && c2 == Paper) || (c1 == Paper && c2 == Rock)
}

fn ai_move<R: Rng>(rng: &mut R, v: [usize; 3]) -> Choice {

    let rand = rng.gen_range(0, v[0] + v[1] + v[2]);
    if rand < v[0] {
        Paper
    } else if rand < v[0] + v[1] {
        Scissors
    } else {
        Rock
    }
}

fn main() {
    let mut rng = rand::thread_rng();

    println!("Rock, paper, scissors!");
    let mut ai_choice: Choice = rng.gen();
    let mut ucf = [0, 0, 0];
    let mut score = [0, 0];

    loop {
        println!("Please input your move: 'r', 'p' or 's'. Type 'q' to quit");

        let mut input = String::new();
        io::stdin()
            .read_line(&mut input)
            .expect("failed to read line");
        let u_choice = match input.to_lowercase().trim() {
            s if s.starts_with('r') => {
                ucf[0] += 1;
                Rock
            }
            s if s.starts_with('p') => {
                ucf[1] += 1;
                Paper
            }
            s if s.starts_with('s') => {
                ucf[2] += 1;
                Scissors
            }
            s if s.starts_with('q') => break,
            _ => {
                println!("Please enter a correct choice!");
                continue;
            }
        };
        println!("You chose {:?}, I chose {:?}.", u_choice, ai_choice);
        if beats(u_choice, ai_choice) {
            score[0] += 1;
            println!("You win!");
        } else if u_choice == ai_choice {
            println!("It's a tie!");
        } else {
            score[1] += 1;
            println!("I win!");
        }
        println!("-Score: You {}, Me {}", score[0], score[1]);

        ai_choice = ai_move(&mut rng, ucf);
    }
    println!("Thank you for the game!");
}


Sierpinski arrowhead curve

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct cursor_tag {
    double x;
    double y;
    int angle;
} cursor_t;

void turn(cursor_t* cursor, int angle) {
    cursor->angle = (cursor->angle + angle) % 360;
}

void draw_line(FILE* out, cursor_t* cursor, double length) {
    double theta = (M_PI * cursor->angle)/180.0;
    cursor->x += length * cos(theta);
    cursor->y += length * sin(theta);
    fprintf(out, "L%g,%g\n", cursor->x, cursor->y);
}

void curve(FILE* out, int order, double length, cursor_t* cursor, int angle) {
    if (order == 0) {
        draw_line(out, cursor, length);
    } else {
        curve(out, order - 1, length/2, cursor, -angle);
        turn(cursor, angle);
        curve(out, order - 1, length/2, cursor, angle);
        turn(cursor, angle);
        curve(out, order - 1, length/2, cursor, -angle);
    }
}

void write_sierpinski_arrowhead(FILE* out, int size, int order) {
    const double margin = 20.0;
    const double side = size - 2.0 * margin;
    cursor_t cursor;
    cursor.angle = 0;
    cursor.x = margin;
    cursor.y = 0.5 * size + 0.25 * sqrt(3) * side;
    if ((order & 1) != 0)
        turn(&cursor, -60);
    fprintf(out, "<svg xmlns='http:
            size, size);
    fprintf(out, "<rect width='100%%' height='100%%' fill='white'/>\n");
    fprintf(out, "<path stroke-width='1' stroke='black' fill='none' d='");
    fprintf(out, "M%g,%g\n", cursor.x, cursor.y);
    curve(out, order, side, &cursor, 60);
    fprintf(out, "'/>\n</svg>\n");
}

int main(int argc, char** argv) {
    const char* filename = "sierpinski_arrowhead.svg";
    if (argc == 2)
        filename = argv[1];
    FILE* out = fopen(filename, "w");
    if (!out) {
        perror(filename);
        return EXIT_FAILURE;
    }
    write_sierpinski_arrowhead(out, 600, 8);
    fclose(out);
    return EXIT_SUCCESS;
}

const SQRT3_2: f64 = 0.86602540378444;

use svg::node::element::path::Data;

struct Cursor {
    x: f64,
    y: f64,
    angle: i32,
}

impl Cursor {
    fn new(x: f64, y: f64) -> Cursor {
        Cursor {
            x: x,
            y: y,
            angle: 0,
        }
    }
    fn turn(&mut self, angle: i32) {
        self.angle = (self.angle + angle) % 360;
    }
    fn draw_line(&mut self, data: Data, length: f64) -> Data {
        let theta = (self.angle as f64).to_radians();
        self.x += length * theta.cos();
        self.y += length * theta.sin();
        data.line_to((self.x, self.y))
    }
}

fn curve(mut data: Data, order: usize, length: f64, cursor: &mut Cursor, angle: i32) -> Data {
    if order == 0 {
        return cursor.draw_line(data, length);
    }
    data = curve(data, order - 1, length / 2.0, cursor, -angle);
    cursor.turn(angle);
    data = curve(data, order - 1, length / 2.0, cursor, angle);
    cursor.turn(angle);
    curve(data, order - 1, length / 2.0, cursor, -angle)
}

fn write_sierpinski_arrowhead(file: &str, size: usize, order: usize) -> std::io::Result<()> {
    use svg::node::element::Path;
    use svg::node::element::Rectangle;

    let margin = 20.0;
    let side = (size as f64) - 2.0 * margin;
    let y = 0.5 * (size as f64) + 0.5 * SQRT3_2 * side;
    let x = margin;
    let mut cursor = Cursor::new(x, y);
    if (order & 1) != 0 {
        cursor.turn(-60);
    }
    let mut data = Data::new().move_to((x, y));
    data = curve(data, order, side, &mut cursor, 60);
    let rect = Rectangle::new()
        .set("width", "100%")
        .set("height", "100%")
        .set("fill", "white");
    let mut document = svg::Document::new()
        .set("width", size)
        .set("height", size)
        .add(rect);
    let path = Path::new()
        .set("fill", "none")
        .set("stroke", "black")
        .set("stroke-width", "1")
        .set("d", data);
    document = document.add(path);
    svg::save(file, &document)
}

fn main() {
    write_sierpinski_arrowhead("sierpinski_arrowhead.svg", 600, 8).unwrap();
}


Snake

char nonblocking_getch();
void positional_putch(int x, int y, char ch);
void millisecond_sleep(int n);
void init_screen();
void update_screen();
void close_screen();

#ifdef __linux__
#define _POSIX_C_SOURCE 200809L
#include <time.h>
#include <ncurses.h>
char nonblocking_getch() { return getch(); }
void positional_putch(int x, int y, char ch) { mvaddch(x, y, ch); }
void millisecond_sleep(int n) {
	struct timespec t = { 0, n * 1000000 };
	nanosleep(&t, 0);

}
void update_screen() { refresh(); }
void init_screen() {
	initscr();
	noecho();
	cbreak();
	nodelay(stdscr, TRUE);
}
void close_screen() { endwin(); }
#endif

#ifdef _WIN32
#error "not implemented"
#endif

#include <time.h>
#include <stdlib.h>

#define w 80
#define h 40

int board[w * h];
int head;
enum Dir { N, E, S, W } dir;
int quit;

enum State { SPACE=0, FOOD=1, BORDER=2 };

void age() {
        int i;
	for(i = 0; i < w * h; ++i)
		if(board[i] < 0)
			++board[i];
}

void plant() {
	int r;
	do
		r = rand() % (w * h);
	while(board[r] != SPACE);
	board[r] = FOOD;
}

void start(void) {
        int i;
	for(i = 0; i < w; ++i)
		board[i] = board[i + (h - 1) * w] = BORDER;
	for(i = 0; i < h; ++i)
		board[i * w] = board[i * w + w - 1] = BORDER;
	head = w * (h - 1 - h % 2) / 2;
	board[head] = -5;
	dir = N;
	quit = 0;
	srand(time(0));
	plant();
}

void step() {
	int len = board[head];
	switch(dir) {
		case N: head -= w; break;
		case S: head += w; break;
		case W: --head; break;
		case E: ++head; break;
	}
	switch(board[head]) {
		case SPACE:
			board[head] = len - 1;
			age();
			break;
		case FOOD:
			board[head] = len - 1;
			plant();
			break;
		default:
			quit = 1;
	}
}

void show() {
	const char * symbol = " @.";
        int i;
	for(i = 0; i < w * h; ++i)
		positional_putch(i / w, i % w,
			board[i] < 0 ? '#' : symbol[board[i]]);
	update_screen();
}

int main (int argc, char * argv[]) {
	init_screen();
	start();
	do {
		show();
		switch(nonblocking_getch()) {
			case 'i': dir = N; break;
			case 'j': dir = W; break;
			case 'k': dir = S; break;
			case 'l': dir = E; break;
			case 'q': quit = 1; break;
		}
		step();
		millisecond_sleep(100);

	}
	while(!quit);
	millisecond_sleep(999);
	close_screen();
	return 0;
}

#![windows_subsystem = "windows"]

use rand::Rng;
use std::{cell::RefCell, rc::Rc};
use winsafe::{co, gui, prelude::*, COLORREF, HBRUSH, HPEN, SIZE};

const STEP: i32 = 3;
const FPS: u32 = 90;
const CELL: i32 = 21;
const FIELD_W: i32 = 20;
const SNAKE_W: i32 = 20;
const ROUNDING: SIZE = SIZE::new(SNAKE_W / 2, SNAKE_W / 2);

const RATIO: i32 = CELL / STEP;
const START_CELL: i32 = FIELD_W / 2 * RATIO;

const TW: i32 = (FIELD_W + 2) * RATIO;
#[derive(Clone, Copy)]
#[repr(i32)]
enum Direction {
    Start = 0,
    A = -1,
    D = 1,
    W = -TW,
    S = TW,
}
use Direction::*;

struct Context {
    wnd: gui::WindowMain,
    snake: Vec<i32>,
    id_r: [i32; 6],
    gap: i32,
    dir: Direction,
    ordered_dir: Direction,
}
impl Context {
    fn new(wnd: gui::WindowMain, len: usize) -> Self {
        Self {
            wnd,
            snake: vec![START_CELL; len.saturating_sub(RATIO as usize)],
            id_r: [START_CELL; 6],
            gap: 0,
            dir: Start,
            ordered_dir: S,
        }
    }
}

pub fn main() {
    let [bg, tail, turn, body, food, head] = [0usize, 1, 2, 3, 4, 5];
    let mut colors = [(0x00, 0xF0, 0xA0); 6];
    colors[bg] = (0x00, 0x50, 0x90);
    colors[food] = (0xFF, 0x50, 0x00);
    colors[head] = (0xFF, 0xFF, 0x00);
    let brushes = COLORREF::new_array(&colors).map(|c| HBRUSH::CreateSolidBrush(c).unwrap());

    let wnd = gui::WindowMain::new(gui::WindowMainOpts {
        title: "Snake - Start: Space, then press W-A-S-D".to_string(),
        size: winsafe::SIZE::new(FIELD_W * RATIO * STEP, FIELD_W * RATIO * STEP),
        ex_style: co::WS_EX::CLIENTEDGE,
        class_bg_brush: brushes[bg],
        ..Default::default()
    });

    let context = Rc::new(RefCell::new(Context::new(wnd.clone(), 0)));

    wnd.on().wm_key_down({
        let context = Rc::clone(&context);
        move |k| {
            let mut ctx = context.borrow_mut();
            match (ctx.dir, k.char_code as u8) {
                (Start, bt @ (b' ' | 113)) => {
                    let len = ctx.snake.len();
                    *ctx = Context::new(ctx.wnd.clone(), if bt == b' ' { len } else { 0 });
                    ctx.wnd.hwnd().InvalidateRect(None, true)?;
                    ctx.wnd.hwnd().SetTimer(1, 1000 / FPS, None)?;
                }
                (W | S, bt @ (b'A' | b'D')) => ctx.ordered_dir = if bt == b'A' { A } else { D },
                (A | D, bt @ (b'S' | b'W')) => ctx.ordered_dir = if bt == b'S' { S } else { W },
                _ => (),
            }
            Ok(())
        }
    });

    wnd.on().wm_timer(1, {
        let context = Rc::clone(&context);
        let cells: Vec<i32> = (1..=FIELD_W)
            .flat_map(|y| (1..=FIELD_W).map(move |x| (y * TW + x) * RATIO))
            .collect();
        move || {
            let mut ctx = context.borrow_mut();
            let new_h = ctx.id_r[head] + ctx.dir as i32;
            ctx.id_r[body] = ctx.id_r[head];
            ctx.id_r[head] = new_h;
            if ctx.gap < 0 {
                ctx.id_r[bg] = ctx.snake.remove(0);
                ctx.id_r[tail] = ctx.snake[0];
                ctx.id_r[turn] = ctx.snake[RATIO as usize / 2];
            }
            ctx.gap -= ctx.gap.signum();
            if ctx.gap == 0 {
                let hw = ctx.wnd.hwnd();
                let eat = new_h == ctx.id_r[food];
                let mut snk_cells: Vec<_> = ctx.snake.iter().step_by(RATIO as usize).collect();
                if !eat && (cells.binary_search(&new_h).is_err() || snk_cells.contains(&&new_h)) {
                    hw.KillTimer(1)?;
                    hw.SetWindowText(&(hw.GetWindowText()? + "  Restart: F2 (with save - Space)"))?;
                    ctx.dir = Start;
                    return Ok(());
                } else if eat || ctx.id_r[food] == START_CELL && ctx.id_r[tail] != START_CELL {
                    if eat {
                        hw.SetWindowText(&format!("Snake - Eaten: {}.", snk_cells.len()))?;
                    }
                    if eat && snk_cells.len() == cells.len() - 2 {
                        hw.SetWindowText(&(hw.GetWindowText()? + " ALL !!!"))?;
                        ctx.id_r[food] = 0;
                    } else if new_h != START_CELL {
                        snk_cells.sort();
                        ctx.id_r[food] = *(cells.iter())
                            .filter(|i| **i != new_h && snk_cells.binary_search(i).is_err())
                            .nth(rand::thread_rng().gen_range(0..cells.len() - snk_cells.len() - 1))
                            .unwrap();
                    }
                }
                ctx.dir = ctx.ordered_dir;
                ctx.gap = if eat { RATIO } else { -RATIO }
            }
            ctx.snake.push(new_h);
            ctx.wnd.hwnd().InvalidateRect(None, false)?;
            Ok(())
        }
    });

    wnd.on().wm_paint(move || {
        let ctx = context.borrow();
        let mut ps = winsafe::PAINTSTRUCT::default();
        let hdc = ctx.wnd.hwnd().BeginPaint(&mut ps)?;
        hdc.SelectObjectPen(HPEN::CreatePen(co::PS::NULL, 0, COLORREF::new(0, 0, 0))?)?;
        for (&id_rect, &brush) in ctx.id_r.iter().zip(&brushes) {
            hdc.SelectObjectBrush(brush)?;
            let left = id_rect % TW * STEP - (STEP * RATIO + SNAKE_W) / 2;
            let top = id_rect / TW * STEP - (STEP * RATIO + SNAKE_W) / 2;
            hdc.RoundRect(
                winsafe::RECT {
                    left,
                    top,
                    right: left + SNAKE_W,
                    bottom: top + SNAKE_W,
                },
                ROUNDING,
            )?;
        }
        ctx.wnd.hwnd().EndPaint(&ps);
        Ok(())
    });

    if let Err(e) = wnd.run_main(None) {
        winsafe::HWND::NULL
            .MessageBox(&e.to_string(), "Uncaught error", co::MB::ICONERROR)
            .unwrap();
    }
}


Sorting algorithms_Pancake sort

int pancake_sort(int *list, unsigned int length)
{

    if(length<2)
        return 0;

    int i,a,max_num_pos,moves;
    moves=0;

    for(i=length;i>1;i--)
    {

        max_num_pos=0;
        for(a=0;a<i;a++)
        {
            if(list[a]>list[max_num_pos])
                max_num_pos=a;
        }

        if(max_num_pos==i-1)

            continue;

        if(max_num_pos)
        {
            moves++;
            do_flip(list, length, max_num_pos+1);
        }

        moves++;
        do_flip(list, length, i);

    }

    return moves;
}

fn pancake_sort<T: Ord>(v: &mut [T]) {
    let len = v.len();

    if len < 2 {
        return;
    }
    for i in (0..len).rev() {

        let max_index = v.iter()
            .take(i + 1)
            .enumerate()
            .max_by_key(|&(_, elem)| elem)
            .map(|(idx, _)| idx)

            .unwrap();

        if max_index != i {
            flip(v, max_index);
            flip(v, i);
        }
    }
}

fn flip<E: PartialOrd>(v: &mut [E], num: usize) {
    v[0..num + 1].reverse();
}

fn main() {

    let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", numbers);
    pancake_sort(&mut numbers);
    println!("After: {:?}", numbers);

    let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
    println!("Before: {:?}", strings);
    pancake_sort(&mut strings);
    println!("After: {:?}", strings);
}


Sorting algorithms_Shell sort

fn shell_sort<T: Ord + Copy>(v: &mut [T]) {
    let mut gap = v.len() / 2;
    let len = v.len();
    while gap > 0 {
        for i in gap..len {
            let temp = v[i];
            let mut j = i;
            while j >= gap && v[j - gap] > temp {
                v[j] = v[j - gap];
                j -= gap;
            }
            v[j] = temp;
        }
        gap /= 2;
    }
}

fn main() {
    let mut numbers = [4i32, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", numbers);
    shell_sort(&mut numbers);
    println!("After: {:?}", numbers);
}


Sorting algorithms_Stooge sort

#include <stdio.h>

#define SWAP(r,s)  do{ t=r; r=s; s=t; } while(0)

void StoogeSort(int a[], int i, int j)
{
   int t;

   if (a[j] < a[i]) SWAP(a[i], a[j]);
   if (j - i > 1)
   {
       t = (j - i + 1) / 3;
       StoogeSort(a, i, j - t);
       StoogeSort(a, i + t, j);
       StoogeSort(a, i, j - t);
   }
}

int main(int argc, char *argv[])
{
   int nums[] = {1, 4, 5, 3, -6, 3, 7, 10, -2, -5, 7, 5, 9, -3, 7};
   int i, n;

   n = sizeof(nums)/sizeof(int);
   StoogeSort(nums, 0, n-1);

   for(i = 0; i <= n-1; i++)
      printf("%5d", nums[i]);

   return 0;
}

fn stoogesort<E>(a: &mut [E])
    where E: PartialOrd
{
    let len = a.len();

    if a.first().unwrap() > a.last().unwrap() {
        a.swap(0, len - 1);
    }
    if len - 1 > 1 {
        let t = len / 3;
        stoogesort(&mut a[..len - 1]);
        stoogesort(&mut a[t..]);
        stoogesort(&mut a[..len - 1]);
    }
}

fn main() {
    let mut numbers = vec![1_i32, 9, 4, 7, 6, 5, 3, 2, 8];
    println!("Before: {:?}", &numbers);
    stoogesort(&mut numbers);
    println!("After: {:?}", &numbers);
}


String comparison

use std::ascii::AsciiExt;

fn main() {

    let a: &str = "abc";
    let b: String = "Bac".to_owned();

    if a == b { println!("The strings are equal") }
    if a != b { println!("The strings are not equal") }
    if a  > &b { println!("The first string is lexically after the second") }
    if a  < &b { println!("The first string is lexically before the second") }
    if a >= &b { println!("The first string is not lexically before the second") }
    if a <= &b { println!("The first string is not lexically after the second") }

    if a.eq_ignore_ascii_case(&b) { println!("Both strings are equal when ignoring case") }

    let a2 = a.to_ascii_uppercase();
    let b2 = b.to_ascii_uppercase();

}


Substring_Top and tail

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main( int argc, char ** argv ){
  const char * str_a = "knight";
  const char * str_b = "socks";
  const char * str_c = "brooms";

  char * new_a = malloc( strlen( str_a ) - 1 );
  char * new_b = malloc( strlen( str_b ) - 1 );
  char * new_c = malloc( strlen( str_c ) - 2 );

  strcpy( new_a, str_a + 1 );
  strncpy( new_b, str_b, strlen( str_b ) - 1 );
  strncpy( new_c, str_c + 1, strlen( str_c ) - 2 );

  printf( "%s\n%s\n%s\n", new_a, new_b, new_c );

  free( new_a );
  free( new_b );
  free( new_c );

  return 0;
}

fn main() {
    let s = String::from("žluťoučký kůň");

    let mut modified = s.clone();
    modified.remove(0);
    println!("{}", modified);

    let mut modified = s.clone();
    modified.pop();
    println!("{}", modified);

    let mut modified = s;
    modified.remove(0);
    modified.pop();
    println!("{}", modified);
}


Sum data type

#include<stdio.h>

typedef union data{
        int i;
        float f;
        char c;
}united;

int main()
{
        united udat;

        udat.i = 5;
        udat.f = 3.14159;
        udat.c = 'C';

        printf("Integer   i = %d , address of i = %p\n",udat.i,&udat.i);
        printf("Float     f = %f , address of f = %p\n",udat.f,&udat.f);
        printf("Character c = %c , address of c = %p\n",udat.c,&udat.c);

        return 0;
}

enum IpAddr {
    V4(u8, u8, u8, u8),
    V6(String),
}

let home = IpAddr::V4(127, 0, 0, 1);

let loopback = IpAddr::V6(String::from("::1"));


Sum of first n cubes

#include <stdio.h>

int main() {
    for (int i = 0, sum = 0; i < 50; ++i) {
        sum += i * i * i;
        printf("%7d%c", sum, (i + 1) % 5 == 0 ? '\n' : ' ');
    }
    return 0;
}


Sutherland-Hodgman polygon clipping

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct { double x, y; } vec_t, *vec;

inline double dot(vec a, vec b)
{
	return a->x * b->x + a->y * b->y;
}

inline double cross(vec a, vec b)
{
	return a->x * b->y - a->y * b->x;
}

inline vec vsub(vec a, vec b, vec res)
{
	res->x = a->x - b->x;
	res->y = a->y - b->y;
	return res;
}

int left_of(vec a, vec b, vec c)
{
	vec_t tmp1, tmp2;
	double x;
	vsub(b, a, &tmp1);
	vsub(c, b, &tmp2);
	x = cross(&tmp1, &tmp2);
	return x < 0 ? -1 : x > 0;
}

int line_sect(vec x0, vec x1, vec y0, vec y1, vec res)
{
	vec_t dx, dy, d;
	vsub(x1, x0, &dx);
	vsub(y1, y0, &dy);
	vsub(x0, y0, &d);

	double dyx = cross(&dy, &dx);
	if (!dyx) return 0;
	dyx = cross(&d, &dx) / dyx;
	if (dyx <= 0 || dyx >= 1) return 0;

	res->x = y0->x + dyx * dy.x;
	res->y = y0->y + dyx * dy.y;
	return 1;
}

typedef struct { int len, alloc; vec v; } poly_t, *poly;

poly poly_new()
{
	return (poly)calloc(1, sizeof(poly_t));
}

void poly_free(poly p)
{
	free(p->v);
	free(p);
}

void poly_append(poly p, vec v)
{
	if (p->len >= p->alloc) {
		p->alloc *= 2;
		if (!p->alloc) p->alloc = 4;
		p->v = (vec)realloc(p->v, sizeof(vec_t) * p->alloc);
	}
	p->v[p->len++] = *v;
}

int poly_winding(poly p)
{
	return left_of(p->v, p->v + 1, p->v + 2);
}

void poly_edge_clip(poly sub, vec x0, vec x1, int left, poly res)
{
	int i, side0, side1;
	vec_t tmp;
	vec v0 = sub->v + sub->len - 1, v1;
	res->len = 0;

	side0 = left_of(x0, x1, v0);
	if (side0 != -left) poly_append(res, v0);

	for (i = 0; i < sub->len; i++) {
		v1 = sub->v + i;
		side1 = left_of(x0, x1, v1);
		if (side0 + side1 == 0 && side0)

			if (line_sect(x0, x1, v0, v1, &tmp))
				poly_append(res, &tmp);
		if (i == sub->len - 1) break;
		if (side1 != -left) poly_append(res, v1);
		v0 = v1;
		side0 = side1;
	}
}

poly poly_clip(poly sub, poly clip)
{
	int i;
	poly p1 = poly_new(), p2 = poly_new(), tmp;

	int dir = poly_winding(clip);
	poly_edge_clip(sub, clip->v + clip->len - 1, clip->v, dir, p2);
	for (i = 0; i < clip->len - 1; i++) {
		tmp = p2; p2 = p1; p1 = tmp;
		if(p1->len == 0) {
			p2->len = 0;
			break;
		}
		poly_edge_clip(p1, clip->v + i, clip->v + i + 1, dir, p2);
	}

	poly_free(p1);
	return p2;
}

int main()
{
	int i;
	vec_t c[] = {{100,100}, {300,100}, {300,300}, {100,300}};

	vec_t s[] = {	{50,150}, {200,50}, {350,150},
			{350,300},{250,300},{200,250},
			{150,350},{100,250},{100,200}};
#define clen (sizeof(c)/sizeof(vec_t))
#define slen (sizeof(s)/sizeof(vec_t))
	poly_t clipper = {clen, 0, c};
	poly_t subject = {slen, 0, s};

	poly res = poly_clip(&subject, &clipper);

	for (i = 0; i < res->len; i++)
		printf("%g %g\n", res->v[i].x, res->v[i].y);

	FILE * eps = fopen("test.eps", "w");
	fprintf(eps, "%%!PS-Adobe-3.0\n%%%%BoundingBox: 40 40 360 360\n"
		"/l {lineto} def /m{moveto} def /s{setrgbcolor} def"
		"/c {closepath} def /gs {fill grestore stroke} def\n");
	fprintf(eps, "0 setlinewidth %g %g m ", c[0].x, c[0].y);
	for (i = 1; i < clen; i++)
		fprintf(eps, "%g %g l ", c[i].x, c[i].y);
	fprintf(eps, "c .5 0 0 s gsave 1 .7 .7 s gs\n");

	fprintf(eps, "%g %g m ", s[0].x, s[0].y);
	for (i = 1; i < slen; i++)
		fprintf(eps, "%g %g l ", s[i].x, s[i].y);
	fprintf(eps, "c 0 .2 .5 s gsave .4 .7 1 s gs\n");

	fprintf(eps, "2 setlinewidth [10 8] 0 setdash %g %g m ",
		res->v[0].x, res->v[0].y);
	for (i = 1; i < res->len; i++)
		fprintf(eps, "%g %g l ", res->v[i].x, res->v[i].y);
	fprintf(eps, "c .5 0 .5 s gsave .7 .3 .8 s gs\n");

	fprintf(eps, "%%%%EOF");
	fclose(eps);
	printf("test.eps written\n");

	return 0;
}

#[derive(Debug, Clone)]
struct Point {
    x: f64,
    y: f64,
}

#[derive(Debug, Clone)]
struct Polygon(Vec<Point>);

fn is_inside(p: &Point, cp1: &Point, cp2: &Point) -> bool {
    (cp2.x - cp1.x) * (p.y - cp1.y) > (cp2.y - cp1.y) * (p.x - cp1.x)
}

fn compute_intersection(cp1: &Point, cp2: &Point, s: &Point, e: &Point) -> Point {
    let dc = Point {
        x: cp1.x - cp2.x,
        y: cp1.y - cp2.y,
    };
    let dp = Point {
        x: s.x - e.x,
        y: s.y - e.y,
    };
    let n1 = cp1.x * cp2.y - cp1.y * cp2.x;
    let n2 = s.x * e.y - s.y * e.x;
    let n3 = 1.0 / (dc.x * dp.y - dc.y * dp.x);
    Point {
        x: (n1 * dp.x - n2 * dc.x) * n3,
        y: (n1 * dp.y - n2 * dc.y) * n3,
    }
}

fn sutherland_hodgman_clip(subject_polygon: &Polygon, clip_polygon: &Polygon) -> Polygon {
    let mut result_ring = subject_polygon.0.clone();
    let mut cp1 = clip_polygon.0.last().unwrap();
    for cp2 in &clip_polygon.0 {
        let input = result_ring;
        let mut s = input.last().unwrap();
        result_ring = vec![];
        for e in &input {
            if is_inside(e, cp1, cp2) {
                if !is_inside(s, cp1, cp2) {
                    result_ring.push(compute_intersection(cp1, cp2, s, e));
                }
                result_ring.push(e.clone());
            } else if is_inside(s, cp1, cp2) {
                result_ring.push(compute_intersection(cp1, cp2, s, e));
            }
            s = e;
        }
        cp1 = cp2;
    }
    Polygon(result_ring)
}

fn main() {
    let _p = |x: f64, y: f64| Point { x, y };
    let subject_polygon = Polygon(vec![
        _p(50.0, 150.0), _p(200.0, 50.0), _p(350.0, 150.0), _p(350.0, 300.0), _p(250.0, 300.0),
        _p(200.0, 250.0), _p(150.0, 350.0), _p(100.0, 250.0), _p(100.0, 200.0),
    ]);
    let clip_polygon = Polygon(vec![
        _p(100.0, 100.0),_p(300.0, 100.0),_p(300.0, 300.0),_p(100.0, 300.0),
    ]);
    let result = sutherland_hodgman_clip(&subject_polygon, &clip_polygon);
    println!("{:?}", result);
}


Text between

char* textBetween(char* thisText, char* startText, char* endText, char* returnText)
{

    char* startPointer = NULL;
    int stringLength = 0;

    char* endPointer = NULL;
    int endLength = 0;

	if (strstr(startText, "start") != NULL)
	{

		startPointer = thisText;
	} else {
		startPointer = strstr(thisText, startText);

    	if (startPointer != NULL)
	    {
        	startPointer = startPointer + strlen(startText);
        }
	}

    if (startPointer != NULL)
    {

		if (strstr(endText, "end") != NULL)
		{

			endPointer = thisText;
			endLength = 0;
		} else {
			endPointer = strstr(startPointer, endText);
			endLength = (int)strlen(endPointer);
		}

        stringLength = strlen(startPointer) - endLength;

        if (stringLength == 0)
        {
		    returnText = "";
		    startPointer = NULL;
        } else {

    	    strncpy(returnText,startPointer, stringLength);
	        returnText[stringLength++] = '\0';
		}

    } else {

	    returnText = "";

    }

    return startPointer;
}

fn text_between<S: Into<String>>(input: S, start: S, end: S) -> String {

    let search_str = input.into();
    let start_str = start.into();
    let end_str = end.into();

    let start_idx  = if start_str.as_str() == "start" {
        0
    } else {
        let start_point = search_str.find(start_str.as_str());
        if start_point.is_none() {
            return String::from("");
        }
        start_point.unwrap() + start_str.len()
    };
    let remaining = &search_str[start_idx..];

    let end_idx = if end_str.as_str() == "end" {
        remaining.len()
    } else {
        remaining.find(end_str.as_str()).unwrap_or(remaining.len())
    };

    return remaining[..end_idx].to_string()
}

fn main() {
    println!("'{}'", text_between("Hello Rosetta Code world", "Hello ", " world"));
    println!("'{}'", text_between("Hello Rosetta Code world", "start", " world"));
    println!("'{}'", text_between("Hello Rosetta Code world", "Hello", "end"));
    println!("'{}'", text_between("

你好嗎
", "
", "
"));
    println!("'{}'", text_between("<text>Hello Rosetta Code world</text>
", "<text>", "
"));
    println!("'{}'", text_between("

hello world

", "
", "
"));
    println!("'{}'", text_between("The quick brown fox jumps over the lazy other fox", "quick ", " fox"));
    println!("'{}'", text_between("One fish two fish red fish blue fish", "fish ", " red"));
    println!("'{}'", text_between("FooBarBazFooBuxQuux", "Foo", "Foo"));
}


Thiele's interpolation formula

#include <stdio.h>
#include <string.h>
#include <math.h>

#define N 32
#define N2 (N * (N - 1) / 2)
#define STEP .05

double xval[N], t_sin[N], t_cos[N], t_tan[N];

double r_sin[N2], r_cos[N2], r_tan[N2];

double rho(double *x, double *y, double *r, int i, int n)
{
	if (n < 0) return 0;
	if (!n) return y[i];

	int idx = (N - 1 - n) * (N - n) / 2 + i;
	if (r[idx] != r[idx])
		r[idx] = (x[i] - x[i + n])
			/ (rho(x, y, r, i, n - 1) - rho(x, y, r, i + 1, n - 1))
			+ rho(x, y, r, i + 1, n - 2);
	return r[idx];
}

double thiele(double *x, double *y, double *r, double xin, int n)
{
	if (n > N - 1) return 1;
	return rho(x, y, r, 0, n) - rho(x, y, r, 0, n - 2)
		+ (xin - x[n]) / thiele(x, y, r, xin, n + 1);
}

#define i_sin(x) thiele(t_sin, xval, r_sin, x, 0)
#define i_cos(x) thiele(t_cos, xval, r_cos, x, 0)
#define i_tan(x) thiele(t_tan, xval, r_tan, x, 0)

int main()
{
	int i;
	for (i = 0; i < N; i++) {
		xval[i] = i * STEP;
		t_sin[i] = sin(xval[i]);
		t_cos[i] = cos(xval[i]);
		t_tan[i] = t_sin[i] / t_cos[i];
	}
	for (i = 0; i < N2; i++)

		r_sin[i] = r_cos[i] = r_tan[i] = 0/0.;

	printf("%16.14f\n", 6 * i_sin(.5));
	printf("%16.14f\n", 3 * i_cos(.5));
	printf("%16.14f\n", 4 * i_tan(1.));
	return 0;
}


Trabb Pardo–Knuth algorithm

#include<math.h>
#include<stdio.h>

int
main ()
{
  double inputs[11], check = 400, result;
  int i;

  printf ("\nPlease enter 11 numbers :");

  for (i = 0; i < 11; i++)
    {
      scanf ("%lf", &inputs[i]);
    }

  printf ("\n\n\nEvaluating f(x) = |x|^0.5 + 5x^3 for the given inputs :");

  for (i = 10; i >= 0; i--)
    {
      result = sqrt (fabs (inputs[i])) + 5 * pow (inputs[i], 3);

      printf ("\nf(%lf) = ");

      if (result > check)
        {
          printf ("Overflow!");
        }

      else
        {
          printf ("%lf", result);
        }
    }

  return 0;
}

use std::io::{self, BufRead};

fn op(x: f32) -> Option<f32> {
    let y = x.abs().sqrt() + 5.0 * x * x * x;
    if y < 400.0 {
        Some(y)
    } else {
        None
    }
}

fn main() {
    println!("Please enter 11 numbers (one number per line)");
    let stdin = io::stdin();

    let xs = stdin
        .lock()
        .lines()
        .map(|ox| ox.unwrap().trim().to_string())
        .flat_map(|s| str::parse::<f32>(&s))
        .take(11)
        .collect::<Vec<_>>();

    for x in xs.into_iter().rev() {
        match op(x) {
            Some(y) => println!("{}", y),
            None => println!("overflow"),
        };
    }
}


Truncate a file

#include <windows.h>
#include <stdio.h>
#include <wchar.h>

void
oops(const wchar_t *message)
{
	wchar_t *buf;
	DWORD error;

	buf = NULL;
	error = GetLastError();
	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
	    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
	    NULL, error, 0, (wchar_t *)&buf, 0, NULL);

	if (buf) {
		fwprintf(stderr, L"%ls: %ls", message, buf);
		LocalFree(buf);
	} else {

		fwprintf(stderr, L"%ls: unknown error 0x%x\n",
		    message, error);
	}
}

int
dotruncate(wchar_t *fn, LARGE_INTEGER fp)
{
	HANDLE fh;

	fh = CreateFileW(fn, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (fh == INVALID_HANDLE_VALUE) {
		oops(fn);
		return 1;
	}

	if (SetFilePointerEx(fh, fp, NULL, FILE_BEGIN) == 0 ||
	    SetEndOfFile(fh) == 0) {
		oops(fn);
		CloseHandle(fh);
		return 1;
	}

	CloseHandle(fh);
	return 0;
}

int
main()
{
	LARGE_INTEGER fp;
	int argc;
	wchar_t **argv, *fn, junk[2];

	argv = CommandLineToArgvW(GetCommandLineW(), &argc);
	if (argv == NULL) {
		oops(L"CommandLineToArgvW");
		return 1;
	}

	if (argc != 3) {
		fwprintf(stderr, L"usage: %ls filename length\n", argv[0]);
		return 1;
	}

	fn = argv[1];

	if (swscanf(argv[2], L"%lld%1ls", &fp.QuadPart, &junk) != 1) {
		fwprintf(stderr, L"%ls: not a number\n", argv[2]);
		return 1;
	}

	return dotruncate(fn, fp);
}

use std::path::Path;
use std::fs;

fn truncate_file<P: AsRef<Path>>(filename: P, filesize: usize) -> Result<(), Error> {
    use Error::*;
    let file = fs::read(&filename).or(Err(NotFound))?;

    if filesize > file.len() {
        return Err(FilesizeTooSmall)
    }

    fs::write(&filename, &file[..filesize]).or(Err(UnableToWrite))?;
    Ok(())
}

#[derive(Debug)]
enum Error {

    NotFound,

    FilesizeTooSmall,

    UnableToWrite,
}


URL encoding

#include <stdio.h>
#include <ctype.h>

char rfc3986[256] = {0};
char html5[256] = {0};

void encode(const char *s, char *enc, char *tb)
{
	for (; *s; s++) {
		if (tb[*s]) sprintf(enc, "%c", tb[*s]);
		else        sprintf(enc, "%%%02X", *s);
		while (*++enc);
	}
}

int main()
{
	const char url[] = "http:
	char enc[(strlen(url) * 3) + 1];

	int i;
	for (i = 0; i < 256; i++) {
		rfc3986[i] = isalnum(i)||i == '~'||i == '-'||i == '.'||i == '_'
			? i : 0;
		html5[i] = isalnum(i)||i == '*'||i == '-'||i == '.'||i == '_'
			? i : (i == ' ') ? '+' : 0;
	}

	encode(url, enc, rfc3986);
	puts(enc);

	return 0;
}

const INPUT: &str = "http:
const MAX_CHAR_VAL: u32 = std::char::MAX as u32;

fn main() {
    let mut buff = [0; 4];
    println!("{}", INPUT.chars()
        .map(|ch| {
            match ch as u32 {
                0 ..= 47 | 58 ..= 64 | 91 ..= 96 | 123 ..= MAX_CHAR_VAL => {
                    ch.encode_utf8(&mut buff);
                    buff[0..ch.len_utf8()].iter().map(|&byte| format!("%{:X}", byte)).collect::<String>()
                },
                _ => ch.to_string(),
            }
        })
        .collect::<String>()
    );
}


Ulam spiral (for primes)

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>

typedef uint32_t bitsieve;

unsigned sieve_check(bitsieve *b, const unsigned v)
{
    if ((v != 2 && !(v & 1)) || (v < 2))
        return 0;
    else
        return !(b[v >> 6] & (1 << (v >> 1 & 31)));
}

bitsieve* sieve(const unsigned v)
{
    unsigned i, j;
    bitsieve *b = calloc((v >> 6) + 1, sizeof(uint32_t));

    for (i = 3; i <= sqrt(v); i += 2)
        if (!(b[i >> 6] & (1 << (i >> 1 & 31))))
            for (j = i*i; j < v; j += (i << 1))
                b[j >> 6] |= (1 << (j >> 1 & 31));

    return b;
}

#define max(x,y) ((x) > (y) ? (x) : (y))

int ulam_get_map(int x, int y, int n)
{
    x -= (n - 1) / 2;
    y -= n / 2;

    int mx = abs(x), my = abs(y);
    int l = 2 * max(mx, my);
    int d = y >= x ? l * 3 + x + y : l - x - y;

    return pow(l - 1, 2) + d;
}

void output_ulam_spiral(int n, const char glyph)
{

    n -= n % 2 == 0 ? 1 : 0;

    const char *spaces = ".................";
    int mwidth = log10(n * n) + 1;

    bitsieve *b = sieve(n * n + 1);
    int x, y;

    for (x = 0; x < n; ++x) {
        for (y = 0; y < n; ++y) {
            int z = ulam_get_map(y, x, n);

            if (glyph == 0) {
                if (sieve_check(b, z))
                    printf("%*d ", mwidth, z);
                else
                    printf("%.*s ", mwidth, spaces);
            }
            else {
                printf("%c", sieve_check(b, z) ? glyph : spaces[0]);
            }
        }
        printf("\n");
    }

    free(b);
}

int main(int argc, char *argv[])
{
    const int n = argc < 2 ? 9 : atoi(argv[1]);

    output_ulam_spiral(n, 0);
    printf("\n");

    output_ulam_spiral(n, '#');
    printf("\n");

    return 0;
}

use std::fmt;

enum Direction { RIGHT, UP, LEFT, DOWN }
use ulam::Direction::*;

fn is_prime(a: u32) -> bool {
    match a {
        2 => true,
        x if x <= 1 || x % 2 == 0 => false,
        _ => {
            let max = f64::sqrt(a as f64) as u32;
            let mut x =  3;
            while x <= max {
                if a % x == 0 { return false; }
                x += 2;
            }
            true
        }
    }
}

pub struct Ulam { u : Vec<Vec<String>> }

impl Ulam {

    pub fn new(n: u32, s: u32, c: char) -> Ulam {
        let mut spiral = vec![vec![String::new(); n as usize]; n as usize];
        let mut dir = RIGHT;
        let mut y = (n / 2) as usize;
        let mut x = if n % 2 == 0 { y - 1 } else { y };
        for j in s..n * n + s {
            spiral[y][x] = if is_prime(j) {
                if c == '\0' { format!("{:4}", j) } else { format!("  {} ", c) }
            }
            else { String::from(" ---") };

            match dir {
                RIGHT => if x as u32 <= n - 1 && spiral[y - 1][x].is_empty() && j > s { dir = UP; },
                UP => if spiral[y][x - 1].is_empty() { dir = LEFT; },
                LEFT => if x == 0 || spiral[y + 1][x].is_empty() { dir = DOWN; },
                DOWN => if spiral[y][x + 1].is_empty() { dir = RIGHT; }
            };

            match dir { RIGHT => x += 1, UP => y -= 1, LEFT => x -= 1, DOWN => y += 1 };
        }
        Ulam { u: spiral }
    }
}

impl fmt::Display for Ulam {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for row in &self.u {
            writeln!(f, "{}", format!("{:?}", row).replace("\"", "").replace(", ", ""));
        };
        writeln!(f, "")
    }
}


Use another language to call a function

#include <stdio.h>

extern int Query (char * Data, size_t * Length);

int main (int argc, char * argv [])
{
   char     Buffer [1024];
   size_t   Size = sizeof (Buffer);

   if (0 == Query (Buffer, &Size))
   {
      printf ("failed to call Query\n");
   }
   else
   {
      char * Ptr = Buffer;
      while (Size-- > 0) putchar (*Ptr++);
      putchar ('\n');
   }
}

#![crate_type = "cdylib"]

extern crate libc;

use std::ffi::CString;

use libc::{c_char, c_int, size_t};

#[no_mangle]
#[allow(non_snake_case)]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn Query(data: *mut c_char, length: *mut size_t) -> c_int {
    let string = "Here am I";
    if *length + 1 < string.len() {
        0
    } else {
        let c_string = CString::new(string).unwrap();
        libc::strcpy(data, c_string.as_ptr());
        *length = string.len();
        1
    }
}


Validate International Securities Identification Number

extern crate luhn_cc;

use luhn_cc::compute_luhn;

fn main() {
    assert_eq!(validate_isin("US0378331005"), true);
    assert_eq!(validate_isin("US0373831005"), false);
    assert_eq!(validate_isin("U50378331005"), false);
    assert_eq!(validate_isin("US03378331005"), false);
    assert_eq!(validate_isin("AU0000XVGZA3"), true);
    assert_eq!(validate_isin("AU0000VXGZA3"), true);
    assert_eq!(validate_isin("FR0000988040"), true);
}

fn validate_isin(isin: &str) -> bool {

    if !isin.chars().all(|x| x.is_alphanumeric()) || isin.len() != 12 {
        return false;
    }
    if !isin[..2].chars().all(|x| x.is_alphabetic())
        || !isin[2..12].chars().all(|x| x.is_alphanumeric())
        || !isin.chars().last().unwrap().is_numeric()
    {
        return false;
    }

    let bytes = isin.as_bytes();

    let s2 = bytes.iter()
        .flat_map(|&c| {
            if c.is_ascii_digit() {
                vec![c]
            }
            else {
                (c + 10 - ('A' as u8)).to_string().into_bytes()
            }
        }).collect::<Vec<u8>>();

    let string = std::str::from_utf8(&s2).unwrap();
    let number = string.parse::<usize>().unwrap();

    return compute_luhn(number);
}


Verify distribution uniformity_Chi-squared test

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

typedef double (* Ifctn)( double t);

double Simpson3_8( Ifctn f, double a, double b, int N)
{
    int j;
    double l1;
    double h = (b-a)/N;
    double h1 = h/3.0;
    double sum = f(a) + f(b);

    for (j=3*N-1; j>0; j--) {
        l1 = (j%3)? 3.0 : 2.0;
        sum += l1*f(a+h1*j) ;
    }
    return h*sum/8.0;
}

#define A 12
double Gamma_Spouge( double z )
{
    int k;
    static double cspace[A];
    static double *coefs = NULL;
    double accum;
    double a = A;

    if (!coefs) {
        double k1_factrl = 1.0;
        coefs = cspace;
        coefs[0] = sqrt(2.0*M_PI);
        for(k=1; k<A; k++) {
            coefs[k] = exp(a-k) * pow(a-k,k-0.5) / k1_factrl;
            k1_factrl *= -k;
        }
    }

    accum = coefs[0];
    for (k=1; k<A; k++) {
        accum += coefs[k]/(z+k);
    }
    accum *= exp(-(z+a)) * pow(z+a, z+0.5);
    return accum/z;
}

double aa1;
double f0( double t)
{
    return  pow(t, aa1)*exp(-t);
}

double GammaIncomplete_Q( double a, double x)
{
    double y, h = 1.5e-2;

    y = aa1 = a-1;
    while((f0(y) * (x-y) > 2.0e-8) && (y < x))   y += .4;
    if (y>x) y=x;

    return 1.0 - Simpson3_8( &f0, 0, y, (int)(y/h))/Gamma_Spouge(a);
}

use statrs::function::gamma::gamma_li;

fn chi_distance(dataset: &[u32]) -> f64 {
    let expected = f64::from(dataset.iter().sum::<u32>()) / dataset.len() as f64;
    dataset
        .iter()
        .fold(0., |acc, &elt| acc + (elt as f64 - expected).powf(2.))
        / expected
}

fn chi2_probability(dof: f64, distance: f64) -> f64 {
    1. - gamma_li(dof * 0.5, distance * 0.5)
}

fn chi2_uniform(dataset: &[u32], significance: f64) -> bool {
    let d = chi_distance(&dataset);
    chi2_probability(dataset.len() as f64 - 1., d) > significance
}

fn main() {
    let dsets = vec![
        vec![199809, 200665, 199607, 200270, 199649],
        vec![522573, 244456, 139979, 71531, 21461],
    ];

    for ds in dsets {
        println!("Data set: {:?}", ds);
        let d = chi_distance(&ds);
        print!("Distance: {:.6} ", d);
        print!(
            "Chi2 probability: {:.6} ",
            chi2_probability(ds.len() as f64 - 1., d)
        );
        print!("Uniform? {}\n", chi2_uniform(&ds, 0.05));
    }
}


Vigenère cipher_Cryptanalysis

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

const char *encoded =
    "MOMUD EKAPV TQEFM OEVHP AJMII CDCTI FGYAG JSPXY ALUYM NSMYH"
    "VUXJE LEPXJ FXGCM JHKDZ RYICU HYPUS PGIGM OIYHF WHTCQ KMLRD"
    "ITLXZ LJFVQ GHOLW CUHLO MDSOE KTALU VYLNZ RFGBX PHVGA LWQIS"
    "FGRPH JOOFW GUBYI LAPLA LCAFA AMKLG CETDW VOELJ IKGJB XPHVG"
    "ALWQC SNWBU BYHCU HKOCE XJEYK BQKVY KIIEH GRLGH XEOLW AWFOJ"
    "ILOVV RHPKD WIHKN ATUHN VRYAQ DIVHX FHRZV QWMWV LGSHN NLVZS"
    "JLAKI FHXUF XJLXM TBLQV RXXHR FZXGV LRAJI EXPRV OSMNP KEPDT"
    "LPRWM JAZPK LQUZA ALGZX GVLKL GJTUI ITDSU REZXJ ERXZS HMPST"
    "MTEOE PAPJH SMFNB YVQUZ AALGA YDNMP AQOWT UHDBV TSMUE UIMVH"
    "QGVRW AEFSP EMPVE PKXZY WLKJA GWALT VYYOB YIXOK IHPDS EVLEV"
    "RVSGB JOGYW FHKBL GLXYA MVKIS KIEHY IMAPX UOISK PVAGN MZHPW"
    "TTZPV XFCCD TUHJH WLAPF YULTB UXJLN SIJVV YOVDJ SOLXG TGRVO"
    "SFRII CTMKO JFCQF KTINQ BWVHG TENLH HOGCS PSFPV GJOKM SIFPR"
    "ZPAAS ATPTZ FTPPD PORRF TAXZP KALQA WMIUD BWNCT LEFKO ZQDLX"
    "BUXJL ASIMR PNMBF ZCYLV WAPVF QRHZV ZGZEF KBYIO OFXYE VOWGB"
    "BXVCB XBAWG LQKCM ICRRX MACUO IKHQU AJEGL OIJHH XPVZW JEWBA"
    "FWAML ZZRXJ EKAHV FASMU LVVUT TGK";

const double freq[] = {
    0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015,
    0.06094, 0.06966, 0.00153, 0.00772, 0.04025, 0.02406, 0.06749,
    0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758,
    0.00978, 0.02360, 0.00150, 0.01974, 0.00074
};

int best_match(const double *a, const double *b) {
    double sum = 0, fit, d, best_fit = 1e100;
    int i, rotate, best_rotate = 0;
    for (i = 0; i < 26; i++)
        sum += a[i];
    for (rotate = 0; rotate < 26; rotate++) {
        fit = 0;
        for (i = 0; i < 26; i++) {
            d = a[(i + rotate) % 26] / sum - b[i];
            fit += d * d / b[i];
        }

        if (fit < best_fit) {
            best_fit = fit;
            best_rotate = rotate;
        }
    }

    return best_rotate;
}

double freq_every_nth(const int *msg, int len, int interval, char *key) {
    double sum, d, ret;
    double out[26], accu[26] = {0};
    int i, j, rot;

    for (j = 0; j < interval; j++) {
        for (i = 0; i < 26; i++)
            out[i] = 0;
        for (i = j; i < len; i += interval)
            out[msg[i]]++;
        key[j] = rot = best_match(out, freq);
        key[j] += 'A';
        for (i = 0; i < 26; i++)
            accu[i] += out[(i + rot) % 26];
    }

    for (i = 0, sum = 0; i < 26; i++)
        sum += accu[i];

    for (i = 0, ret = 0; i < 26; i++) {
        d = accu[i] / sum - freq[i];
        ret += d * d / freq[i];
    }

    key[interval] = '\0';
    return ret;
}

int main() {
    int txt[strlen(encoded)];
    int len = 0, j;
    char key[100];
    double fit, best_fit = 1e100;

    for (j = 0; encoded[j] != '\0'; j++)
        if (isupper(encoded[j]))
            txt[len++] = encoded[j] - 'A';

    for (j = 1; j < 30; j++) {
        fit = freq_every_nth(txt, len, j, key);
        printf("%f, key length: %2d, %s", fit, j, key);
        if (fit < best_fit) {
            best_fit = fit;
            printf(" <--- best so far");
        }
        printf("\n");
    }

    return 0;
}

use std::iter::FromIterator;

const CRYPTOGRAM: &str = "MOMUD EKAPV TQEFM OEVHP AJMII CDCTI FGYAG JSPXY ALUYM NSMYH
VUXJE LEPXJ FXGCM JHKDZ RYICU HYPUS PGIGM OIYHF WHTCQ KMLRD
ITLXZ LJFVQ GHOLW CUHLO MDSOE KTALU VYLNZ RFGBX PHVGA LWQIS
FGRPH JOOFW GUBYI LAPLA LCAFA AMKLG CETDW VOELJ IKGJB XPHVG
ALWQC SNWBU BYHCU HKOCE XJEYK BQKVY KIIEH GRLGH XEOLW AWFOJ
ILOVV RHPKD WIHKN ATUHN VRYAQ DIVHX FHRZV QWMWV LGSHN NLVZS
JLAKI FHXUF XJLXM TBLQV RXXHR FZXGV LRAJI EXPRV OSMNP KEPDT
LPRWM JAZPK LQUZA ALGZX GVLKL GJTUI ITDSU REZXJ ERXZS HMPST
MTEOE PAPJH SMFNB YVQUZ AALGA YDNMP AQOWT UHDBV TSMUE UIMVH
QGVRW AEFSP EMPVE PKXZY WLKJA GWALT VYYOB YIXOK IHPDS EVLEV
RVSGB JOGYW FHKBL GLXYA MVKIS KIEHY IMAPX UOISK PVAGN MZHPW
TTZPV XFCCD TUHJH WLAPF YULTB UXJLN SIJVV YOVDJ SOLXG TGRVO
SFRII CTMKO JFCQF KTINQ BWVHG TENLH HOGCS PSFPV GJOKM SIFPR
ZPAAS ATPTZ FTPPD PORRF TAXZP KALQA WMIUD BWNCT LEFKO ZQDLX
BUXJL ASIMR PNMBF ZCYLV WAPVF QRHZV ZGZEF KBYIO OFXYE VOWGB
BXVCB XBAWG LQKCM ICRRX MACUO IKHQU AJEGL OIJHH XPVZW JEWBA
FWAML ZZRXJ EKAHV FASMU LVVUT TGK";

const FREQUENCIES: [f32; 26] = [
    0.08167, 0.01492, 0.02202, 0.04253, 0.12702, 0.02228, 0.02015, 0.06094, 0.06966, 0.00153,
    0.01292, 0.04025, 0.02406, 0.06749, 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09356,
    0.02758, 0.00978, 0.02560, 0.00150, 0.01994, 0.00077,
];

fn best_match(a: &[f32]) -> u8 {
    let sum: f32 = a.iter().sum();
    let mut best_fit = std::f32::MAX;
    let mut best_rotate = 0;
    for rotate in 0..=25 {
        let mut fit = 0.;
        for i in 0..=25 {
            let char_freq = FREQUENCIES[i];
            let idx = (i + rotate as usize) % 26 as usize;
            let d = a[idx] / sum - char_freq;
            fit += d * d / char_freq;
        }
        if fit < best_fit {
            best_fit = fit;
            best_rotate = rotate;
        }
    }

    best_rotate
}

fn freq_every_nth(msg: &[u8], key: &mut [char]) -> f32 {
    let len = msg.len();
    let interval = key.len();
    let mut accu = [0.; 26];
    for j in 0..interval {
        let mut out = [0.; 26];
        for i in (j..len).step_by(interval) {
            let idx = msg[i] as usize;
            out[idx] += 1.;
        }
        let rot = best_match(&out);
        key[j] = char::from(rot + b'A');
        for i in 0..=25 {
            let idx: usize = (i + rot as usize) % 26;
            accu[i] += out[idx];
        }
    }
    let sum: f32 = accu.iter().sum();
    let mut ret = 0.;
    for i in 0..=25 {
        let char_freq = FREQUENCIES[i];
        let d = accu[i] / sum - char_freq;
        ret += d * d / char_freq;
    }
    ret
}

fn decrypt(text: &str, key: &str) -> String {
    let key_chars_cycle = key.as_bytes().iter().map(|b| *b as i32).cycle();
    let is_ascii_uppercase = |c: &u8| (b'A'..=b'Z').contains(c);
    text.as_bytes()
        .iter()
        .filter(|c| is_ascii_uppercase(c))
        .map(|b| *b as i32)
        .zip(key_chars_cycle)
        .fold(String::new(), |mut acc, (c, key_char)| {
            let ci: u8 = ((c - key_char + 26) % 26) as u8;
            acc.push(char::from(b'A' + ci));
            acc
        })
}
fn main() {
    let enc = CRYPTOGRAM
        .split_ascii_whitespace()
        .collect::<Vec<_>>()
        .join("");
    let cryptogram: Vec<u8> = enc.as_bytes().iter().map(|b| u8::from(b - b'A')).collect();
    let mut best_fit = std::f32::MAX;
    let mut best_key = String::new();
    for j in 1..=26 {
        let mut key = vec!['\0'; j];
        let fit = freq_every_nth(&cryptogram, &mut key);
        let s_key = String::from_iter(key);
        if fit < best_fit {
            best_fit = fit;
            best_key = s_key;
        }
    }

    println!("best key: {}", &best_key);
    println!("\nDecrypted text:\n{}", decrypt(&enc, &best_key));
}


Water collected between towers

#include<stdlib.h>
#include<stdio.h>

int getWater(int* arr,int start,int end,int cutoff){
	int i, sum = 0;

	for(i=start;i<=end;i++)
		sum += ((arr[cutoff] > arr[i])?(arr[cutoff] - arr[i]):0);

	return sum;
}

int netWater(int* arr,int size){
	int i, j, ref1, ref2, marker, markerSet = 0,sum = 0;

	if(size<3)
		return 0;

	for(i=0;i<size-1;i++){
		start:if(i!=size-2 && arr[i]>arr[i+1]){
				ref1 = i;

				for(j=ref1+1;j<size;j++){
					if(arr[j]>=arr[ref1]){
						ref2 = j;

						sum += getWater(arr,ref1+1,ref2-1,ref1);

						i = ref2;

						goto start;
					}

					else if(j!=size-1 && arr[j] < arr[j+1] && (markerSet==0||(arr[j+1]>=arr[marker]))){
						marker = j+1;
						markerSet = 1;
					}
				}

				if(markerSet==1){
					sum += getWater(arr,ref1+1,marker-1,marker);

					i = marker;

					markerSet = 0;

					goto start;
				}
			}
		}

	return sum;
}

int main(int argC,char* argV[])
{
	int *arr,i;

	if(argC==1)
		printf("Usage : %s <followed by space separated series of integers>");
	else{
		arr = (int*)malloc((argC-1)*sizeof(int));

		for(i=1;i<argC;i++)
			arr[i-1] = atoi(argV[i]);

		printf("Water collected : %d",netWater(arr,argC-1));
	}

	return 0;
}

use std::cmp::min;

fn getfill(pattern: &[usize]) -> usize {
    let mut total = 0;
    for (idx, val) in pattern.iter().enumerate() {
        let l_peak = pattern[..idx].iter().max();
        let r_peak = pattern[idx + 1..].iter().max();
        if l_peak.is_some() && r_peak.is_some() {
            let peak = min(l_peak.unwrap(), r_peak.unwrap());
            if peak > val {
                total += peak - val;
            }
        }
    }
    total
}

fn main() {
    let patterns = vec![
        vec![1, 5, 3, 7, 2],
        vec![5, 3, 7, 2, 6, 4, 5, 9, 1, 2],
        vec![2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],
        vec![5, 5, 5, 5],
        vec![5, 6, 7, 8],
        vec![8, 7, 7, 6],
        vec![6, 7, 10, 7, 6],
    ];

    for pattern in patterns {
        println!("pattern: {:?}, fill: {}", &pattern, getfill(&pattern));
    }
}


Wireworld

#define ANIMATE_VT100_POSIX
#include <stdio.h>
#include <string.h>
#ifdef ANIMATE_VT100_POSIX
#include <time.h>
#endif

char world_7x14[2][512] = {
  {
    "+-----------+\n"
    "|tH.........|\n"
    "|.   .      |\n"
    "|   ...     |\n"
    "|.   .      |\n"
    "|Ht.. ......|\n"
    "+-----------+\n"
  }
};

void next_world(const char *in, char *out, int w, int h)
{
  int i;

  for (i = 0; i < w*h; i++) {
    switch (in[i]) {
    case ' ': out[i] = ' '; break;
    case 't': out[i] = '.'; break;
    case 'H': out[i] = 't'; break;
    case '.': {
      int hc = (in[i-w-1] == 'H') + (in[i-w] == 'H') + (in[i-w+1] == 'H') +
               (in[i-1]   == 'H')                    + (in[i+1]   == 'H') +
               (in[i+w-1] == 'H') + (in[i+w] == 'H') + (in[i+w+1] == 'H');
      out[i] = (hc == 1 || hc == 2) ? 'H' : '.';
      break;
    }
    default:
      out[i] = in[i];
    }
  }
  out[i] = in[i];
}

int main()
{
  int f;

  for (f = 0; ; f = 1 - f) {
    puts(world_7x14[f]);
    next_world(world_7x14[f], world_7x14[1-f], 14, 7);
#ifdef ANIMATE_VT100_POSIX
    printf("\x1b[%dA", 8);
    printf("\x1b[%dD", 14);
    {
      static const struct timespec ts = { 0, 100000000 };
      nanosleep(&ts, 0);
    }
#endif
  }

  return 0;
}

use std::str::FromStr;

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum State {
    Empty,
    Conductor,
    ElectronTail,
    ElectronHead,
}

impl State {
    fn next(&self, e_nearby: usize) -> State {
        match self {
            State::Empty => State::Empty,
            State::Conductor => {
                if e_nearby == 1 || e_nearby == 2 {
                    State::ElectronHead
                } else {
                    State::Conductor
                }
            }
            State::ElectronTail => State::Conductor,
            State::ElectronHead => State::ElectronTail,
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub struct WireWorld {
    pub width: usize,
    pub height: usize,
    pub data: Vec<State>,
}

impl WireWorld {
    pub fn new(width: usize, height: usize) -> Self {
        WireWorld {
            width,
            height,
            data: vec![State::Empty; width * height],
        }
    }

    pub fn get(&self, x: usize, y: usize) -> Option<State> {
        if x >= self.width || y >= self.height {
            None
        } else {
            self.data.get(y * self.width + x).copied()
        }
    }

    pub fn set(&mut self, x: usize, y: usize, state: State) {
        self.data[y * self.width + x] = state;
    }

    fn neighbors<F>(&self, x: usize, y: usize, mut f: F) -> usize
        where F: FnMut(State) -> bool
    {
        let (x, y) = (x as i32, y as i32);
        let neighbors = [(x-1,y-1),(x-1,y),(x-1,y+1),(x,y-1),(x,y+1),(x+1,y-1),(x+1,y),(x+1,y+1)];

        neighbors.iter().filter_map(|&(x, y)| self.get(x as usize, y as usize)).filter(|&s| f(s)).count()
    }

    pub fn next(&mut self) {
        let mut next_state = vec![];
        for y in 0..self.height {
            for x in 0..self.width {
                let e_count = self.neighbors(x, y, |e| e == State::ElectronHead);
                next_state.push(self.get(x, y).unwrap().next(e_count));
            }
        }
        self.data = next_state;
    }
}

impl FromStr for WireWorld {
    type Err = ();
    fn from_str(s: &str) -> Result<WireWorld, ()> {
        let s = s.trim();
        let height = s.lines().count();
        let width = s.lines().map(|l| l.trim_end().len()).max().unwrap_or(0);
        let mut world = WireWorld::new(width, height);

        for (y, line) in s.lines().enumerate() {
            for (x, ch) in line.trim_end().chars().enumerate() {
                let state = match ch {
                    '.' => State::Conductor,
                    't' => State::ElectronTail,
                    'H' => State::ElectronHead,
                    _ => State::Empty,
                };
                world.set(x, y, state);
            }
        }
        Ok(world)
    }
}


Yellowstone sequence

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct lnode_t {
    struct lnode_t *prev;
    struct lnode_t *next;
    int v;
} Lnode;

Lnode *make_list_node(int v) {
    Lnode *node = malloc(sizeof(Lnode));
    if (node == NULL) {
        return NULL;
    }
    node->v = v;
    node->prev = NULL;
    node->next = NULL;
    return node;
}

void free_lnode(Lnode *node) {
    if (node == NULL) {
        return;
    }

    node->v = 0;
    node->prev = NULL;
    free_lnode(node->next);
    node->next = NULL;
}

typedef struct list_t {
    Lnode *front;
    Lnode *back;
    size_t len;
} List;

List *make_list() {
    List *list = malloc(sizeof(List));
    if (list == NULL) {
        return NULL;
    }
    list->front = NULL;
    list->back = NULL;
    list->len = 0;
    return list;
}

void free_list(List *list) {
    if (list == NULL) {
        return;
    }
    list->len = 0;
    list->back = NULL;
    free_lnode(list->front);
    list->front = NULL;
}

void list_insert(List *list, int v) {
    Lnode *node;

    if (list == NULL) {
        return;
    }

    node = make_list_node(v);
    if (list->front == NULL) {
        list->front = node;
        list->back = node;
        list->len = 1;
    } else {
        node->prev = list->back;
        list->back->next = node;
        list->back = node;
        list->len++;
    }
}

void list_print(List *list) {
    Lnode *it;

    if (list == NULL) {
        return;
    }

    for (it = list->front; it != NULL; it = it->next) {
        printf("%d ", it->v);
    }
}

int list_get(List *list, int idx) {
    Lnode *it = NULL;

    if (list != NULL && list->front != NULL) {
        int i;
        if (idx < 0) {
            it = list->back;
            i = -1;
            while (it != NULL && i > idx) {
                it = it->prev;
                i--;
            }
        } else {
            it = list->front;
            i = 0;
            while (it != NULL && i < idx) {
                it = it->next;
                i++;
            }
        }
    }

    if (it == NULL) {
        return INT_MIN;
    }
    return it->v;
}

typedef struct mnode_t {
    int k;
    bool v;
    struct mnode_t *next;
} Mnode;

Mnode *make_map_node(int k, bool v) {
    Mnode *node = malloc(sizeof(Mnode));
    if (node == NULL) {
        return node;
    }
    node->k = k;
    node->v = v;
    node->next = NULL;
    return node;
}

void free_mnode(Mnode *node) {
    if (node == NULL) {
        return;
    }
    node->k = 0;
    node->v = false;
    free_mnode(node->next);
    node->next = NULL;
}

typedef struct map_t {
    Mnode *front;
} Map;

Map *make_map() {
    Map *map = malloc(sizeof(Map));
    if (map == NULL) {
        return NULL;
    }
    map->front = NULL;
    return map;
}

void free_map(Map *map) {
    if (map == NULL) {
        return;
    }
    free_mnode(map->front);
    map->front = NULL;
}

void map_insert(Map *map, int k, bool v) {
    if (map == NULL) {
        return;
    }
    if (map->front == NULL) {
        map->front = make_map_node(k, v);
    } else {
        Mnode *it = map->front;
        while (it->next != NULL) {
            it = it->next;
        }
        it->next = make_map_node(k, v);
    }
}

bool map_get(Map *map, int k) {
    if (map != NULL) {
        Mnode *it = map->front;
        while (it != NULL && it->k != k) {
            it = it->next;
        }
        if (it != NULL) {
            return it->v;
        }
    }
    return false;
}

int gcd(int u, int v) {
    if (u < 0) u = -u;
    if (v < 0) v = -v;
    if (v) {
        while ((u %= v) && (v %= u));
    }
    return u + v;
}

List *yellow(size_t n) {
    List *a;
    Map *b;
    int i;

    a = make_list();
    list_insert(a, 1);
    list_insert(a, 2);
    list_insert(a, 3);

    b = make_map();
    map_insert(b, 1, true);
    map_insert(b, 2, true);
    map_insert(b, 3, true);

    i = 4;

    while (n > a->len) {
        if (!map_get(b, i) && gcd(i, list_get(a, -1)) == 1 && gcd(i, list_get(a, -2)) > 1) {
            list_insert(a, i);
            map_insert(b, i, true);
            i = 4;
        }
        i++;
    }

    free_map(b);
    return a;
}

int main() {
    List *a = yellow(30);
    list_print(a);
    free_list(a);
    putc('\n', stdout);
    return 0;
}

use num::integer::gcd;
use plotters::prelude::*;
use std::collections::HashSet;

fn yellowstone_sequence() -> impl std::iter::Iterator<Item = u32> {
    let mut sequence: HashSet<u32> = HashSet::new();
    let mut min = 1;
    let mut n = 0;
    let mut n1 = 0;
    let mut n2 = 0;
    std::iter::from_fn(move || {
        n2 = n1;
        n1 = n;
        if n < 3 {
            n += 1;
        } else {
            n = min;
            while !(!sequence.contains(&n) && gcd(n1, n) == 1 && gcd(n2, n) > 1) {
                n += 1;
            }
        }
        sequence.insert(n);
        while sequence.contains(&min) {
            sequence.remove(&min);
            min += 1;
        }
        Some(n)
    })
}

fn plot_yellowstone(filename: &str) -> Result<(), Box<dyn std::error::Error>> {
    let root = BitMapBackend::new(filename, (800, 600)).into_drawing_area();
    root.fill(&WHITE)?;
    let mut chart = ChartBuilder::on(&root)
        .caption("Yellowstone Sequence", ("sans-serif", 24).into_font())
        .margin(10)
        .x_label_area_size(20)
        .y_label_area_size(20)
        .build_ranged(0usize..100usize, 0u32..180u32)?;
    chart.configure_mesh().draw()?;
    chart.draw_series(LineSeries::new(
        yellowstone_sequence().take(100).enumerate(),
        &BLUE,
    ))?;
    Ok(())
}

fn main() {
    println!("First 30 Yellowstone numbers:");
    for y in yellowstone_sequence().take(30) {
        print!("{} ", y);
    }
    println!();
    match plot_yellowstone("yellowstone.png") {
        Ok(()) => {}
        Err(error) => eprintln!("Error: {}", error),
    }
}