Data update
This commit is contained in:
parent
9817d9b99b
commit
07c7092a52
|
|
@ -0,0 +1 @@
|
|||
../../Task/Averages-Median/AArch64-Assembly
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Pell-numbers/ALGOL-68
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Ascending-primes/ALGOL-W
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Descending-primes/ALGOL-W
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Bell-numbers/ANSI-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Remove-duplicate-elements/ANSI-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Trabb-Pardo-Knuth-algorithm/ANSI-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Duffinian-numbers/Applesoft-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Loop-over-multiple-arrays-simultaneously/Applesoft-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Primality-by-trial-division/Applesoft-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Find-Chess960-starting-position-identifier/C++
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/C++
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Strip-a-set-of-characters-from-a-string/Chipmunk-Basic
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Tau-number/Chipmunk-Basic
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Temperature-conversion/Chipmunk-Basic
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Tau-number/GW-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Sum-digits-of-an-integer/Gambas
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Even-or-odd/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/FizzBuzz/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Look-and-say-sequence/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Loop-over-multiple-arrays-simultaneously/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Palindrome-detection/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Quine/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Reverse-words-in-a-string/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Rot-13/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Sorting-algorithms-Bogosort/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Strip-a-set-of-characters-from-a-string/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Temperature-conversion/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Test-a-function/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Time-a-function/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Variadic-function/Insitux
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Elementary-cellular-automaton-Infinite-length/Java
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Elementary-cellular-automaton-Random-number-generator/Java
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Equal-prime-and-composite-sums/Java
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/File-size-distribution/Java
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Golden-ratio-Convergence/Lua
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Sum-digits-of-an-integer/MSX-Basic
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Tau-number/MSX-Basic
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Bell-numbers/Modula-2
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Temperature-conversion/Quite-BASIC
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Radical-of-an-integer/REXX
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Jordan-P-lya-numbers/Raku
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/Raku
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/ADFGVX-cipher/Rust
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Digital-root-Multiplicative-digital-root/Rust
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/EKG-sequence-convergence/Rust
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../Task/Soundex/Rust
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import system'routines;
|
||||
import system'collections;
|
||||
import system'culture;
|
||||
import extensions;
|
||||
import extensions'routines;
|
||||
|
||||
|
|
@ -9,7 +10,7 @@ extension op
|
|||
{
|
||||
var list := ArrayList.load(blocks);
|
||||
|
||||
^ nil == (cast string(self)).upperCase().seekEach:(ch)
|
||||
^ nil == (cast string(self)).toUpper().seekEach:(ch)
|
||||
{
|
||||
var index := list.indexOfElement
|
||||
((word => word.indexOf(0, ch) != -1).asComparator());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
// This version formats the encrypted text in 5 character blocks, as the historical version apparently did.
|
||||
|
||||
use fastrand::shuffle;
|
||||
use std::collections::HashMap;
|
||||
|
||||
static ADFGVX: &str = "ADFGVX";
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
struct CPair(char, char);
|
||||
|
||||
/// The WWI German ADFGVX cipher.
|
||||
struct AdfgvxCipher {
|
||||
polybius: Vec<char>,
|
||||
key: Vec<char>,
|
||||
encode: HashMap<char, CPair>,
|
||||
decode: HashMap<CPair, char>,
|
||||
}
|
||||
|
||||
/// Set up the encoding and decoding for the ADFGVX cipher.
|
||||
fn cipher(allowed_chars: String, encrypt_key: String) -> AdfgvxCipher {
|
||||
let alphabet = allowed_chars.to_uppercase().chars().collect::<Vec<_>>();
|
||||
assert!(alphabet.len() == ADFGVX.len() * ADFGVX.len());
|
||||
let mut polybius = alphabet.clone();
|
||||
shuffle(&mut polybius);
|
||||
let key = encrypt_key.to_uppercase().chars().collect::<Vec<_>>();
|
||||
let adfgvx: Vec<char> = String::from(ADFGVX).chars().collect();
|
||||
let mut pairs: Vec<CPair> = [CPair(' ', ' '); 0].to_vec();
|
||||
for c1 in &adfgvx {
|
||||
for c2 in &adfgvx {
|
||||
pairs.push(CPair(*c1, *c2));
|
||||
}
|
||||
}
|
||||
let mut encode: HashMap<char, CPair> = HashMap::new();
|
||||
for i in 0..pairs.len() {
|
||||
encode.insert(polybius[i], pairs[i].clone());
|
||||
}
|
||||
let mut decode = HashMap::new();
|
||||
for (k, v) in &encode {
|
||||
decode.insert(v.clone(), *k);
|
||||
}
|
||||
return AdfgvxCipher {
|
||||
polybius,
|
||||
key,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
}
|
||||
|
||||
/// Encrypt with the ADFGVX cipher.
|
||||
fn encrypt(a: &AdfgvxCipher, msg: String) -> String {
|
||||
let umsg: Vec<char> = msg
|
||||
.clone()
|
||||
.to_uppercase()
|
||||
.chars()
|
||||
.filter(|c| a.polybius.contains(c))
|
||||
.collect();
|
||||
let mut fractionated = vec![' '; 0].to_vec();
|
||||
for c in umsg {
|
||||
let cp = a.encode.get(&c).unwrap();
|
||||
fractionated.push(cp.0);
|
||||
fractionated.push(cp.1);
|
||||
}
|
||||
let ncols = a.key.len();
|
||||
let extra = fractionated.len() % ncols;
|
||||
if extra > 0 {
|
||||
fractionated.append(&mut vec!['\u{00}'; ncols - extra]);
|
||||
}
|
||||
let nrows = fractionated.len() / ncols;
|
||||
let mut sortedkey = a.key.clone();
|
||||
sortedkey.sort();
|
||||
let mut ciphertext = String::from("");
|
||||
let mut textlen = 0;
|
||||
for j in 0..ncols {
|
||||
let k = a.key.iter().position(|c| *c == sortedkey[j]).unwrap();
|
||||
for i in 0..nrows {
|
||||
let ch: char = fractionated[i * ncols + k];
|
||||
if ch != '\u{00}' {
|
||||
ciphertext.push(ch);
|
||||
textlen += 1;
|
||||
if textlen % 5 == 0 {
|
||||
ciphertext.push(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
/// Decrypt with the ADFGVX cipher. Does not depend on spacing of encoded text
|
||||
fn decrypt(a: &AdfgvxCipher, cod: String) -> String {
|
||||
let chars: Vec<char> = cod.chars().filter(|c| *c != ' ').collect();
|
||||
let mut sortedkey = a.key.clone();
|
||||
sortedkey.sort();
|
||||
let order: Vec<usize> = sortedkey
|
||||
.iter()
|
||||
.map(|c| a.key.iter().position(|kc| kc == c).unwrap())
|
||||
.collect();
|
||||
let originalorder: Vec<usize> = a
|
||||
.key
|
||||
.iter()
|
||||
.map(|c| sortedkey.iter().position(|kc| kc == c).unwrap())
|
||||
.collect();
|
||||
let q = chars.len() / a.key.len();
|
||||
let r = chars.len() % a.key.len();
|
||||
let strides: Vec<usize> = order
|
||||
.iter()
|
||||
.map(|i| {q + {if r > *i {1} else {0}}}).collect();
|
||||
let mut starts: Vec<usize> = vec![0_usize; 1].to_vec();
|
||||
let mut stridesum = 0;
|
||||
for i in 0..strides.len() - 1 {
|
||||
stridesum += strides[i];
|
||||
starts.push(stridesum);
|
||||
}
|
||||
let ends: Vec<usize> = (0..a.key.len()).map(|i| (starts[i] + strides[i])).collect(); // shuffled ends of columns
|
||||
let cols: Vec<Vec<char>> = originalorder
|
||||
.iter()
|
||||
.map(|i| (chars[starts[*i]..ends[*i]]).to_vec())
|
||||
.collect(); // get reordered columns
|
||||
let nrows = (chars.len() - 1) / a.key.len() + 1;
|
||||
let mut fractionated = vec![' '; 0].to_vec();
|
||||
for i in 0..nrows {
|
||||
for j in 0..a.key.len() {
|
||||
if i < cols[j].len() {
|
||||
fractionated.push(cols[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut decoded = String::from("");
|
||||
for i in 0..fractionated.len() - 1 {
|
||||
if i % 2 == 0 {
|
||||
let cp = CPair(fractionated[i], fractionated[i + 1]);
|
||||
decoded.push(*a.decode.get(&cp).unwrap());
|
||||
}
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let msg = String::from("ATTACKAT1200AM");
|
||||
let encrypt_key = String::from("volcanism");
|
||||
let allowed_chars: String = String::from("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
let adf = cipher(allowed_chars, encrypt_key.clone());
|
||||
println!("Message: {msg}");
|
||||
println!("Polybius: {:?}", adf.polybius.iter().collect::<String>());
|
||||
println!("Key: {encrypt_key}");
|
||||
let encrypted_message = encrypt(&adf, msg.clone());
|
||||
println!("Encoded: {encrypted_message}");
|
||||
let decoded = decrypt(&adf, encrypted_message);
|
||||
println!("Decoded: {decoded:?}");
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
begin % find all primes with strictly ascending digits - translation of Lua %
|
||||
|
||||
% quicksorts v, the bounds of v must be specified in lb and ub %
|
||||
procedure quicksort ( integer array v( * )
|
||||
; integer value lb, ub
|
||||
) ;
|
||||
if ub > lb then begin
|
||||
% more than one element, so must sort %
|
||||
integer left, right, pivot;
|
||||
left := lb;
|
||||
right := ub;
|
||||
% choosing the middle element of the array as the pivot %
|
||||
pivot := v( left + ( ( right + 1 ) - left ) div 2 );
|
||||
while begin
|
||||
while left <= ub and v( left ) < pivot do left := left + 1;
|
||||
while right >= lb and v( right ) > pivot do right := right - 1;
|
||||
left <= right
|
||||
end do begin
|
||||
integer swap;
|
||||
swap := v( left );
|
||||
v( left ) := v( right );
|
||||
v( right ) := swap;
|
||||
left := left + 1;
|
||||
right := right - 1
|
||||
end while_left_le_right ;
|
||||
quicksort( v, lb, right );
|
||||
quicksort( v, left, ub )
|
||||
end quicksort ;
|
||||
|
||||
% returns true if n is prime, false otherwise %
|
||||
logical procedure is_prime( integer value n ) ;
|
||||
if n < 2 then false
|
||||
else if n rem 2 = 0 then n = 2
|
||||
else if n rem 3 = 0 then n = 3
|
||||
else begin
|
||||
logical prime; prime := true;
|
||||
for f := 5 step 6 until entier( sqrt( n ) ) do begin
|
||||
if n rem f = 0 or n rem ( f + 2 ) = 0 then begin
|
||||
prime := false;
|
||||
goto done
|
||||
end if_n_rem_f_eq_0_or_n_rem_f_plus_2_eq_0
|
||||
end for_f;
|
||||
done: prime
|
||||
end is_prime ;
|
||||
|
||||
% increments n and also returns its new value %
|
||||
integer procedure inc ( integer value result n ) ; begin n := n + 1; n end;
|
||||
|
||||
% sets primes to the list of ascending primes and lenPrimes to the %
|
||||
% number of ascending primes - primes must be big enough, e.g. have 511 %
|
||||
% elements %
|
||||
procedure ascending_primes ( integer array primes ( * )
|
||||
; integer result lenPrimes
|
||||
) ;
|
||||
begin
|
||||
integer array digits ( 1 :: 9 );
|
||||
integer array candidates ( 1 :: 6000 );
|
||||
integer lenCandidates;
|
||||
candidates( 1 ) := 0;
|
||||
lenCandidates := 1;
|
||||
lenPrimes := 0;
|
||||
for i := 1 until 9 do digits( i ) := i;
|
||||
for i := 1 until 9 do begin
|
||||
for j := 1 until lenCandidates do begin
|
||||
integer cValue; cValue := candidates( j ) * 10 + digits( i );
|
||||
if is_prime( cValue ) then primes( inc( lenPrimes ) ) := cValue;
|
||||
candidates( inc( lenCandidates ) ) := cValue
|
||||
end for_j
|
||||
end for_i ;
|
||||
quickSort( primes, 1, lenPrimes );
|
||||
end ascending_primes ;
|
||||
|
||||
begin % find the ascending primes and print them %
|
||||
integer array primes ( 1 :: 512 );
|
||||
integer lenPrimes;
|
||||
ascending_primes( primes, lenPrimes );
|
||||
for i := 1 until lenPrimes do begin
|
||||
writeon( i_w := 8, s_w := 0, " ", primes( i ) );
|
||||
if i rem 10 = 0 then write()
|
||||
end for_i
|
||||
end
|
||||
end.
|
||||
|
|
@ -0,0 +1,583 @@
|
|||
/* ARM assembly AARCH64 Raspberry PI 3B */
|
||||
/* program averageMed64.s */
|
||||
/* use quickselect look pseudo code in wikipedia quickselect */
|
||||
|
||||
/************************************/
|
||||
/* Constantes */
|
||||
/************************************/
|
||||
/* for this file see task include a file in language AArch64 assembly*/
|
||||
.include "../includeConstantesARM64.inc"
|
||||
|
||||
/*********************************/
|
||||
/* Initialized data */
|
||||
/*********************************/
|
||||
.data
|
||||
szMessResultValue: .asciz "Result : "
|
||||
szCarriageReturn: .asciz "\n"
|
||||
|
||||
.align 4
|
||||
TableNumber: .double 4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2
|
||||
.equ NBELEMENTS, (. - TableNumber) / 8
|
||||
TableNumber2: .double 4.1, 7.2, 1.7, 9.3, 4.4, 3.2
|
||||
.equ NBELEMENTS2, (. - TableNumber2) / 8
|
||||
/*********************************/
|
||||
/* UnInitialized data */
|
||||
/*********************************/
|
||||
.bss
|
||||
sZoneConv: .skip 24
|
||||
sZoneConv1: .skip 24
|
||||
/*********************************/
|
||||
/* code section */
|
||||
/*********************************/
|
||||
.text
|
||||
.global main
|
||||
main: // entry of program
|
||||
ldr x0,qAdrTableNumber // address number table
|
||||
mov x1,#0 // index first item
|
||||
mov x2,#NBELEMENTS -1 // index last item
|
||||
bl searchMedian
|
||||
ldr x0,qAdrTableNumber2 // address number table 2
|
||||
mov x1,#0 // index first item
|
||||
mov x2,#NBELEMENTS2 -1 // index last item
|
||||
bl searchMedian
|
||||
|
||||
100: // standard end of the program
|
||||
mov x0, #0 // return code
|
||||
mov x8, #EXIT // request to exit program
|
||||
svc #0 // perform the system call
|
||||
|
||||
qAdrszCarriageReturn: .quad szCarriageReturn
|
||||
qAdrTableNumber: .quad TableNumber
|
||||
qAdrTableNumber2: .quad TableNumber2
|
||||
qAdrsZoneConv: .quad sZoneConv
|
||||
qAdrszMessResultValue: .quad szMessResultValue
|
||||
/***************************************************/
|
||||
/* search median term in float array */
|
||||
/***************************************************/
|
||||
/* x0 contains the address of table */
|
||||
/* x1 contains index of first item */
|
||||
/* x2 contains index of last item */
|
||||
searchMedian:
|
||||
stp x1,lr,[sp,-16]! // save registers TODO: à revoir génération
|
||||
stp x2,x3,[sp,-16]! // save registers
|
||||
stp x4,x5,[sp,-16]! // save registers
|
||||
|
||||
mov x19,x0 // save array address
|
||||
add x4,x1,x2
|
||||
add x4,x4,#1 // sum numbers terms
|
||||
tst x4,#1 // odd ?
|
||||
bne 1f
|
||||
lsr x3,x4,#1 // compute median index
|
||||
bl select // call selection
|
||||
fmov d0,x0 // save first result
|
||||
sub x3,x3,#1 // second term
|
||||
mov x0,x19
|
||||
bl select // call selection
|
||||
fmov d1,x0 // save 2ieme résult
|
||||
fadd d0,d0,d1 // compute average two résults
|
||||
mov x0,#2
|
||||
fmov d1,x0
|
||||
scvtf d1,d1 // conversion integer -> float
|
||||
fdiv d0,d0,d1
|
||||
b 2f
|
||||
1: // even
|
||||
lsr x3,x4,#1
|
||||
bl select // call selection
|
||||
fmov d0,x0
|
||||
2:
|
||||
ldr x0,qAdrsZoneConv // conversion float in decimal string
|
||||
bl convertirFloat
|
||||
mov x0,#3 // and display result
|
||||
ldr x1,qAdrszMessResultValue
|
||||
ldr x2,qAdrsZoneConv
|
||||
ldr x3,qAdrszCarriageReturn
|
||||
bl displayStrings
|
||||
100: // end function
|
||||
|
||||
ldp x4,x5,[sp],16 // restaur 2 registers
|
||||
ldp x2,x3,[sp],16 // restaur 2 registers
|
||||
ldp x1,lr,[sp],16 // restaur 2 registers
|
||||
ret
|
||||
|
||||
/***************************************************/
|
||||
/* Appel récursif selection */
|
||||
/***************************************************/
|
||||
/* x0 contains the address of table */
|
||||
/* x1 contains index of first item */
|
||||
/* x2 contains index of last item */
|
||||
/* x3 contains search index */
|
||||
select:
|
||||
stp x1,lr,[sp,-16]! // save registers
|
||||
stp x2,x3,[sp,-16]! // save registers
|
||||
stp x4,x5,[sp,-16]! // save registers
|
||||
stp x6,x7,[sp,-16]! // save registers
|
||||
mov x6,x3 // save search index
|
||||
cmp x1,x2 // first = last ?
|
||||
bne 1f
|
||||
ldr x0,[x0,x1,lsl #3] // return value of first index
|
||||
b 100f // yes -> end
|
||||
1:
|
||||
add x3,x1,x2
|
||||
lsr x3,x3,#1 // compute median pivot
|
||||
mov x4,x0 // save x0
|
||||
mov x5,x2 // save x2
|
||||
bl partition // cutting.quado 2 parts
|
||||
cmp x6,x0 // pivot is ok ?
|
||||
bne 2f
|
||||
ldr x0,[x4,x0,lsl #3] // yes -> return value
|
||||
b 100f
|
||||
2:
|
||||
bgt 3f
|
||||
sub x2,x0,#1 // index partition - 1
|
||||
mov x0,x4 // array address
|
||||
mov x3,x6 // search index
|
||||
bl select // select lower part
|
||||
b 100f
|
||||
3:
|
||||
add x1,x0,#1 // index begin = index partition + 1
|
||||
mov x0,x4 // array address
|
||||
mov x2,x5 // last item
|
||||
mov x3,x6 // search index
|
||||
bl select // select higter part
|
||||
|
||||
100: // end function
|
||||
ldp x6,x7,[sp],16 // restaur 2 registers
|
||||
ldp x4,x5,[sp],16 // restaur 2 registers
|
||||
ldp x2,x3,[sp],16 // restaur 2 registers
|
||||
ldp x1,lr,[sp],16 // restaur 2 registers
|
||||
ret // return to address lr x30
|
||||
/******************************************************************/
|
||||
/* Partition table elements */
|
||||
/******************************************************************/
|
||||
/* x0 contains the address of table */
|
||||
/* x1 contains index of first item */
|
||||
/* x2 contains index of last item */
|
||||
/* x3 contains index of pivot */
|
||||
partition:
|
||||
stp x1,lr,[sp,-16]! // save registers
|
||||
stp x2,x3,[sp,-16]! // save registers
|
||||
stp x4,x5,[sp,-16]! // save registers
|
||||
stp x6,x7,[sp,-16]! // save registers
|
||||
ldr x4,[x0,x3,lsl #3] // load value of pivot
|
||||
ldr x5,[x0,x2,lsl #3] // load value last index
|
||||
str x5,[x0,x3,lsl #3] // swap value of pivot
|
||||
str x4,[x0,x2,lsl #3] // and value last index
|
||||
mov x3,x1 // init with first index
|
||||
1: // begin loop
|
||||
ldr x6,[x0,x3,lsl #3] // load value
|
||||
cmp x6,x4 // compare loop value and pivot value
|
||||
bge 2f
|
||||
ldr x5,[x0,x1,lsl #3] // if < swap value table
|
||||
str x6,[x0,x1,lsl #3]
|
||||
str x5,[x0,x3,lsl #3]
|
||||
add x1,x1,#1 // and increment index 1
|
||||
2:
|
||||
add x3,x3,#1 // increment index 2
|
||||
cmp x3,x2 // end ?
|
||||
blt 1b // no loop
|
||||
ldr x5,[x0,x1,lsl #3] // swap value
|
||||
str x4,[x0,x1,lsl #3]
|
||||
str x5,[x0,x2,lsl #3]
|
||||
mov x0,x1 // return index partition
|
||||
100:
|
||||
ldp x6,x7,[sp],16 // restaur 2 registers
|
||||
ldp x4,x5,[sp],16 // restaur 2 registers
|
||||
ldp x2,x3,[sp],16 // restaur 2 registers
|
||||
ldp x1,lr,[sp],16 // restaur 2 registers
|
||||
ret // return to address lr x30
|
||||
|
||||
/***************************************************/
|
||||
/* display multi strings */
|
||||
/* new version 24/05/2023 */
|
||||
/***************************************************/
|
||||
/* x0 contains number strings address */
|
||||
/* x1 address string1 */
|
||||
/* x2 address string2 */
|
||||
/* x3 address string3 */
|
||||
/* x4 address string4 */
|
||||
/* x5 address string5 */
|
||||
/* x6 address string5 */
|
||||
/* x7 address string6 */
|
||||
displayStrings: // INFO: displayStrings
|
||||
stp x8,lr,[sp,-16]! // save registers
|
||||
stp x2,fp,[sp,-16]! // save registers
|
||||
add fp,sp,#32 // save paraméters address (4 registers saved * 8 bytes)
|
||||
mov x8,x0 // save strings number
|
||||
cmp x8,#0 // 0 string -> end
|
||||
ble 100f
|
||||
mov x0,x1 // string 1
|
||||
bl affichageMess
|
||||
cmp x8,#1 // number > 1
|
||||
ble 100f
|
||||
mov x0,x2
|
||||
bl affichageMess
|
||||
cmp x8,#2
|
||||
ble 100f
|
||||
mov x0,x3
|
||||
bl affichageMess
|
||||
cmp x8,#3
|
||||
ble 100f
|
||||
mov x0,x4
|
||||
bl affichageMess
|
||||
cmp x8,#4
|
||||
ble 100f
|
||||
mov x0,x5
|
||||
bl affichageMess
|
||||
cmp x8,#5
|
||||
ble 100f
|
||||
mov x0,x6
|
||||
bl affichageMess
|
||||
cmp x8,#6
|
||||
ble 100f
|
||||
mov x0,x7
|
||||
bl affichageMess
|
||||
|
||||
100:
|
||||
ldp x2,fp,[sp],16 // restaur registers
|
||||
ldp x8,lr,[sp],16 // restaur registers
|
||||
ret
|
||||
/******************************************************************/
|
||||
/* Conversion Float */
|
||||
/******************************************************************/
|
||||
/* d0 contains Float */
|
||||
/* x0 contains address conversion area mini 20 charactèrs */
|
||||
/* x0 return result length */
|
||||
/* see https://blog.benoitblanchon.fr/lightweight-float-to-string/ */
|
||||
convertirFloat:
|
||||
stp x1,lr,[sp,-16]! // save registres
|
||||
stp x2,x3,[sp,-16]! // save registres
|
||||
stp x4,x5,[sp,-16]! // save registres
|
||||
stp x6,x7,[sp,-16]! // save registres
|
||||
stp x8,x9,[sp,-16]! // save registres
|
||||
stp d1,d2,[sp,-16]! // save registres
|
||||
mov x6,x0 // save area address
|
||||
fmov x0,d0
|
||||
mov x8,#0 // result length
|
||||
mov x3,#'+'
|
||||
strb w3,[x6] // signe + forcing
|
||||
mov x2,x0
|
||||
tbz x2,63,1f
|
||||
mov x2,1
|
||||
lsl x2,x2,63
|
||||
bic x0,x0,x2
|
||||
mov x3,#'-' // sign -
|
||||
strb w3,[x6]
|
||||
1:
|
||||
adds x8,x8,#1 // next position
|
||||
cmp x0,#0 // case 0 positive or negative
|
||||
bne 2f
|
||||
mov x3,#'0'
|
||||
strb w3,[x6,x8] // store character 0
|
||||
adds x8,x8,#1
|
||||
strb wzr,[x6,x8] // store 0 final
|
||||
mov x0,x8 // return length
|
||||
b 100f
|
||||
2:
|
||||
ldr x2,iMaskExposant
|
||||
mov x1,x0
|
||||
and x1,x1,x2 // exposant
|
||||
cmp x1,x2
|
||||
bne 4f
|
||||
tbz x0,51,3f // test bit 51 to zéro
|
||||
mov x2,#'N' // case Nan. store byte no possible store integer
|
||||
strb w2,[x6] // area no aligned
|
||||
mov x2,#'a'
|
||||
strb w2,[x6,#1]
|
||||
mov x2,#'n'
|
||||
strb w2,[x6,#2]
|
||||
mov x2,#0 // 0 final
|
||||
strb w2,[x6,#3]
|
||||
mov x0,#3
|
||||
b 100f
|
||||
3: // case infini positive or négative
|
||||
mov x2,#'I'
|
||||
strb w2,[x6,x8]
|
||||
adds x8,x8,#1
|
||||
mov x2,#'n'
|
||||
strb w2,[x6,x8]
|
||||
adds x8,x8,#1
|
||||
mov x2,#'f'
|
||||
strb w2,[x6,x8]
|
||||
adds x8,x8,#1
|
||||
mov x2,#0
|
||||
strb w2,[x6,x8]
|
||||
mov x0,x8
|
||||
b 100f
|
||||
4:
|
||||
bl normaliserFloat
|
||||
mov x5,x0 // save exposant
|
||||
fcvtzu d2,d0
|
||||
fmov x0,d2 // part integer
|
||||
scvtf d1,d2 // conversion float
|
||||
fsub d1,d0,d1 // extraction part fractional
|
||||
ldr d2,dConst1
|
||||
fmul d1,d2,d1 // to crop it in full
|
||||
fcvtzu d1,d1 // convertion integer
|
||||
fmov x4,d1 // fract value
|
||||
// conversion part integer to x0
|
||||
mov x2,x6 // save address begin area
|
||||
adds x6,x6,x8
|
||||
mov x1,x6
|
||||
bl conversion10
|
||||
add x6,x6,x0
|
||||
mov x3,#','
|
||||
strb w3,[x6]
|
||||
adds x6,x6,#1
|
||||
|
||||
mov x0,x4 // conversion part fractionnaire
|
||||
mov x1,x6
|
||||
bl conversion10SP
|
||||
add x6,x6,x0
|
||||
sub x6,x6,#1
|
||||
// remove trailing zeros
|
||||
5:
|
||||
ldrb w0,[x6]
|
||||
cmp w0,#'0'
|
||||
bne 6f
|
||||
sub x6,x6,#1
|
||||
b 5b
|
||||
6:
|
||||
cmp w0,#','
|
||||
bne 7f
|
||||
sub x6,x6,#1
|
||||
7:
|
||||
cmp x5,#0 // if exposant = 0 no display
|
||||
bne 8f
|
||||
add x6,x6,#1
|
||||
b 10f
|
||||
8:
|
||||
add x6,x6,#1
|
||||
mov x3,#'E'
|
||||
strb w3,[x6]
|
||||
add x6,x6,#1
|
||||
mov x0,x5 // conversion exposant
|
||||
mov x3,x0
|
||||
tbz x3,63,9f // exposant negative ?
|
||||
neg x0,x0
|
||||
mov x3,#'-'
|
||||
strb w3,[x6]
|
||||
adds x6,x6,#1
|
||||
9:
|
||||
mov x1,x6
|
||||
bl conversion10
|
||||
add x6,x6,x0
|
||||
10:
|
||||
strb wzr,[x6] // store 0 final
|
||||
adds x6,x6,#1
|
||||
mov x0,x6
|
||||
subs x0,x0,x2 // retour de la longueur de la zone
|
||||
subs x0,x0,#1 // sans le 0 final
|
||||
|
||||
100:
|
||||
ldp d1,d2,[sp],16 // restaur registres
|
||||
ldp x8,x9,[sp],16 // restaur registres
|
||||
ldp x6,x7,[sp],16 // restaur registres
|
||||
ldp x4,x5,[sp],16 // restaur registres
|
||||
ldp x2,x3,[sp],16 // restaur registres
|
||||
ldp x1,lr,[sp],16 // restaur registres
|
||||
ret
|
||||
|
||||
iMaskExposant: .quad 0x7FF<<52
|
||||
dConst1: .double 0f1E17
|
||||
|
||||
/***************************************************/
|
||||
/* normaliser float */
|
||||
/***************************************************/
|
||||
/* x0 contain float value (always positive value and <> Nan) */
|
||||
/* d0 return new value */
|
||||
/* x0 return exposant */
|
||||
normaliserFloat:
|
||||
stp x1,lr,[sp,-16]! // save registers
|
||||
fmov d0,x0 // value float
|
||||
mov x0,#0 // exposant
|
||||
ldr d1,dConstE7 // no normalisation for value < 1E7
|
||||
fcmp d0,d1
|
||||
blo 10f // if d0 < dConstE7
|
||||
|
||||
ldr d1,dConstE256
|
||||
fcmp d0,d1
|
||||
blo 1f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#256
|
||||
1:
|
||||
|
||||
ldr d1,dConstE128
|
||||
fcmp d0,d1
|
||||
blo 1f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#128
|
||||
1:
|
||||
ldr d1,dConstE64
|
||||
fcmp d0,d1
|
||||
blo 1f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#64
|
||||
1:
|
||||
ldr d1,dConstE32
|
||||
fcmp d0,d1
|
||||
blo 1f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#32
|
||||
1:
|
||||
ldr d1,dConstE16
|
||||
fcmp d0,d1
|
||||
blo 2f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#16
|
||||
2:
|
||||
ldr d1,dConstE8
|
||||
fcmp d0,d1
|
||||
blo 3f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#8
|
||||
3:
|
||||
ldr d1,dConstE4
|
||||
fcmp d0,d1
|
||||
blo 4f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#4
|
||||
4:
|
||||
ldr d1,dConstE2
|
||||
fcmp d0,d1
|
||||
blo 5f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#2
|
||||
5:
|
||||
ldr d1,dConstE1
|
||||
fcmp d0,d1
|
||||
blo 10f
|
||||
fdiv d0,d0,d1
|
||||
adds x0,x0,#1
|
||||
|
||||
10:
|
||||
ldr d1,dConstME5 // pas de normalisation pour les valeurs > 1E-5
|
||||
fcmp d0,d1
|
||||
bhi 100f // fin
|
||||
|
||||
ldr d1,dConstME255
|
||||
fcmp d0,d1
|
||||
bhi 11f
|
||||
ldr d1,dConstE256
|
||||
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#256
|
||||
11:
|
||||
|
||||
ldr d1,dConstME127
|
||||
fcmp d0,d1
|
||||
bhi 11f
|
||||
ldr d1,dConstE128
|
||||
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#128
|
||||
11:
|
||||
|
||||
ldr d1,dConstME63
|
||||
fcmp d0,d1
|
||||
bhi 11f
|
||||
ldr d1,dConstE64
|
||||
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#64
|
||||
11:
|
||||
|
||||
ldr d1,dConstME31
|
||||
fcmp d0,d1
|
||||
bhi 11f
|
||||
ldr d1,dConstE32
|
||||
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#32
|
||||
11:
|
||||
ldr d1,dConstME15
|
||||
fcmp d0,d1
|
||||
bhi 12f
|
||||
ldr d1,dConstE16
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#16
|
||||
12:
|
||||
ldr d1,dConstME7
|
||||
fcmp d0,d1
|
||||
bhi 13f
|
||||
ldr d1,dConstE8
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#8
|
||||
13:
|
||||
ldr d1,dConstME3
|
||||
fcmp d0,d1
|
||||
bhi 14f
|
||||
ldr d1,dConstE4
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#4
|
||||
14:
|
||||
ldr d1,dConstME1
|
||||
fcmp d0,d1
|
||||
bhi 15f
|
||||
ldr d1,dConstE2
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#2
|
||||
15:
|
||||
ldr d1,dConstE0
|
||||
fcmp d0,d1
|
||||
bhi 100f
|
||||
ldr d1,dConstE1
|
||||
fmul d0,d0,d1
|
||||
subs x0,x0,#1
|
||||
|
||||
100: // fin standard de la fonction
|
||||
ldp x1,lr,[sp],16 // restaur registres
|
||||
ret
|
||||
.align 2
|
||||
dConstE7: .double 0f1E7
|
||||
dConstE256: .double 0f1E256
|
||||
dConstE128: .double 0f1E128
|
||||
dConstE64: .double 0f1E64
|
||||
dConstE32: .double 0f1E32
|
||||
dConstE16: .double 0f1E16
|
||||
dConstE8: .double 0f1E8
|
||||
dConstE4: .double 0f1E4
|
||||
dConstE2: .double 0f1E2
|
||||
dConstE1: .double 0f1E1
|
||||
dConstME5: .double 0f1E-5
|
||||
dConstME255: .double 0f1E-255
|
||||
dConstME127: .double 0f1E-127
|
||||
dConstME63: .double 0f1E-63
|
||||
dConstME31: .double 0f1E-31
|
||||
dConstME15: .double 0f1E-15
|
||||
dConstME7: .double 0f1E-7
|
||||
dConstME3: .double 0f1E-3
|
||||
dConstME1: .double 0f1E-1
|
||||
dConstE0: .double 0f1E0
|
||||
|
||||
/******************************************************************/
|
||||
/* Décimal Conversion */
|
||||
/******************************************************************/
|
||||
/* x0 contain value et x1 address conversion area */
|
||||
conversion10SP:
|
||||
stp x1,lr,[sp,-16]! // save registers
|
||||
stp x2,x3,[sp,-16]! // save registers
|
||||
stp x4,x5,[sp,-16]! // save registers
|
||||
mov x5,x1
|
||||
mov x4,#16
|
||||
mov x2,x0
|
||||
mov x1,#10 // décimal conversion
|
||||
1: // conversion loop
|
||||
mov x0,x2 // copy begin number or quotient
|
||||
udiv x2,x0,x1 // division by 10
|
||||
msub x3,x1,x2,x0 // compute remainder
|
||||
add x3,x3,#48 // compute digit
|
||||
strb w3,[x5,x4] // store byte address area (x5) + offset (x4)
|
||||
subs x4,x4,#1 // position precedente
|
||||
bge 1b
|
||||
strb wzr,[x5,16] // 0 final
|
||||
100:
|
||||
ldp x4,x5,[sp],16 // restaur registers
|
||||
ldp x2,x3,[sp],16 // restaur registers
|
||||
ldp x1,lr,[sp],16 // restaur registers
|
||||
ret
|
||||
|
||||
/***************************************************/
|
||||
/* ROUTINES INCLUDE */
|
||||
/***************************************************/
|
||||
/* for this file see task include a file in language AArch64 assembly*/
|
||||
.include "../includeARM64.inc"
|
||||
|
|
@ -202,6 +202,7 @@ displayStrings: @ INFO: displayStrings
|
|||
/* s0 contains Float */
|
||||
/* r0 contains address conversion area mini 20 charactèrs*/
|
||||
/* r0 return result length */
|
||||
/* see https://blog.benoitblanchon.fr/lightweight-float-to-string/ */
|
||||
convertirFloat:
|
||||
push {r1-r7,lr}
|
||||
vpush {s0-s2}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
100 REM Bell numbers
|
||||
110 LET MaxN = 14
|
||||
120 OPTION BASE 0
|
||||
130 DIM A(13) ! i.e. DIM A(MaxN - 1), ANSI BASIC does not allow expressions in the bound arguments.
|
||||
140 FOR I = 0 TO MaxN - 1
|
||||
150 LET A(I) = 0
|
||||
160 NEXT I
|
||||
170 LET N = 0
|
||||
180 LET A(0) = 1
|
||||
190 PRINT USING "B(##) = #########": N, A(0)
|
||||
200 DO WHILE N < MaxN
|
||||
210 LET A(N) = A(0)
|
||||
220 FOR J = N TO 1 STEP -1
|
||||
230 LET A(J - 1) = A(J - 1) + A(J)
|
||||
240 NEXT J
|
||||
250 LET N = N + 1
|
||||
260 PRINT USING "B(##) = #########": N, A(0)
|
||||
270 LOOP
|
||||
280 END
|
||||
|
|
@ -9,11 +9,11 @@ program BellNumbers;
|
|||
uses SysUtils; // only for the display
|
||||
|
||||
const
|
||||
MAX_INDEX = 25; // maximum index within the limits of int64
|
||||
MAX_N = 25; // maximum index of Bell number within the limits of int64
|
||||
var
|
||||
n : integer; // index of Bell number
|
||||
j : integer; // loop variable
|
||||
a : array [0..MAX_INDEX - 1] of int64; // working array to build up B_n
|
||||
a : array [0..MAX_N - 1] of int64; // working array to build up B_n
|
||||
|
||||
{ Subroutine to display that a[0] is the Bell number B_n }
|
||||
procedure Display();
|
||||
|
|
@ -26,7 +26,7 @@ begin
|
|||
n := 0;
|
||||
a[0] := 1;
|
||||
Display(); // some programmers would prefer Display;
|
||||
while (n < MAX_INDEX) do begin // and give begin a line to itself
|
||||
while (n < MAX_N) do begin // and give begin a line to itself
|
||||
a[n] := a[0];
|
||||
for j := n downto 1 do inc( a[j - 1], a[j]);
|
||||
inc(n);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
MODULE BellNumbers;
|
||||
|
||||
FROM STextIO IMPORT
|
||||
WriteLn, WriteString;
|
||||
FROM SWholeIO IMPORT
|
||||
WriteInt;
|
||||
|
||||
CONST
|
||||
MaxN = 14;
|
||||
|
||||
VAR
|
||||
A: ARRAY [0 .. MaxN - 1] OF CARDINAL;
|
||||
I, J, N: CARDINAL;
|
||||
|
||||
PROCEDURE DisplayRow(N, BellNum: CARDINAL);
|
||||
BEGIN
|
||||
WriteString("B(");
|
||||
WriteInt(N, 2);
|
||||
WriteString(") = ");
|
||||
WriteInt(BellNum, 9);
|
||||
WriteLn
|
||||
END DisplayRow;
|
||||
|
||||
BEGIN
|
||||
FOR I := 0 TO MaxN - 1 DO
|
||||
A[I] := 0
|
||||
END;
|
||||
N := 0;
|
||||
A[0] := 1;
|
||||
DisplayRow(N, A[0]);
|
||||
WHILE N < MaxN DO
|
||||
A[N] := A[0];
|
||||
FOR J := N TO 1 BY -1 DO
|
||||
A[J - 1] := A[J - 1] + A[J]
|
||||
END;
|
||||
N := N + 1;
|
||||
DisplayRow(N, A[0])
|
||||
END
|
||||
END BellNumbers.
|
||||
|
|
@ -1,26 +1,18 @@
|
|||
' Bell numbers
|
||||
DECLARE SUB DisplayRow (N%, BellNum&)
|
||||
CONST MAXINDEX% = 14
|
||||
DIM A&(MAXINDEX% - 1)
|
||||
FOR I% = 0 TO MAXINDEX% - 1
|
||||
CONST MAXN% = 14
|
||||
DIM A&(MAXN% - 1)
|
||||
FOR I% = 0 TO MAXN% - 1
|
||||
A&(I%) = 0
|
||||
NEXT I%
|
||||
N% = 0
|
||||
A&(0) = 1
|
||||
DisplayRow N%, A&(0)
|
||||
WHILE N% < MAXINDEX%
|
||||
PRINT USING "B(##) = #########"; N%; A&(0)
|
||||
WHILE N% < MAXN%
|
||||
A&(N%) = A&(0)
|
||||
FOR J% = N% TO 1 STEP -1
|
||||
A&(J% - 1) = A&(J% - 1) + A&(J%)
|
||||
NEXT J%
|
||||
N% = N% + 1
|
||||
DisplayRow N%, A&(0)
|
||||
PRINT USING "B(##) = #########"; N%; A&(0)
|
||||
WEND
|
||||
END
|
||||
|
||||
SUB DisplayRow (N%, BellNum&)
|
||||
PRINT "B(";
|
||||
PRINT USING "##"; N%;
|
||||
PRINT ") = ";
|
||||
PRINT USING "#########"; BellNum&
|
||||
END SUB
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
' Bell numbers
|
||||
CONST MAXINDEX% = 14
|
||||
DIM A&(MAXINDEX% - 1)
|
||||
FOR I% = 0 TO MAXINDEX% - 1
|
||||
CONST MAXN% = 14
|
||||
DIM A&(MAXN% - 1)
|
||||
FOR I% = 0 TO MAXN% - 1
|
||||
A&(I%) = 0
|
||||
NEXT I%
|
||||
N% = 0
|
||||
A&(0) = 1
|
||||
PRINT FORMAT$("B(%2d) = %9d", N%, A&(0))
|
||||
WHILE N% < MAXINDEX%
|
||||
WHILE N% < MAXN%
|
||||
A&(N%) = A&(0)
|
||||
FOR J% = N% TO 1 STEP -1
|
||||
A&(J% - 1) = A&(J% - 1) + A&(J%)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
\Bell numbers
|
||||
code CrLf=9, IntOut=11, Text=12;
|
||||
define MaxIndex = 14;
|
||||
integer A(MaxIndex), I, J, N;
|
||||
define MaxN = 14;
|
||||
integer A(MaxN), I, J, N;
|
||||
|
||||
begin
|
||||
for I:= 0 to MaxIndex - 1 do A(I):= 0;
|
||||
for I:= 0 to MaxN - 1 do A(I):= 0;
|
||||
N:= 0; A(0):= 1;
|
||||
Text(0, "B("); IntOut(0, N); Text(0, ") = "); IntOut(0, A(0)); CrLf(0);
|
||||
while N < MaxIndex do
|
||||
while N < MaxN do
|
||||
begin
|
||||
A(N):= A(0);
|
||||
for J:= N downto 1 do A(J - 1):= A(J - 1) + A(J);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class Bifid {
|
|||
public:
|
||||
Bifid(const int32_t n, std::string_view text) {
|
||||
if ( text.length() != n * n ) {
|
||||
throw new std::invalid_argument("Incorrect length of text");
|
||||
throw std::invalid_argument("Incorrect length of text");
|
||||
}
|
||||
|
||||
grid.resize(n);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
: .exists ( str len -- ) 2dup file-status nip 0= if ." exists" else ." does not exist" then type ;
|
||||
s" input.txt" .exists
|
||||
s" /input.txt" .exists
|
||||
s" docs" .exists
|
||||
s" /docs" .exists
|
||||
: .exists ( str len -- )
|
||||
2dup file-status nip 0= if
|
||||
." exists: "
|
||||
else
|
||||
." does not exist: "
|
||||
then
|
||||
type
|
||||
;
|
||||
|
||||
s" input.txt" .exists cr
|
||||
s" /input.txt" .exists cr
|
||||
s" docs" .exists cr
|
||||
s" /docs" .exists cr
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
addN(n) = x -> n + x
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
begin % find all primes with strictly descending digits - translation of Lua %
|
||||
|
||||
% quicksorts v, the bounds of v must be specified in lb and ub %
|
||||
procedure quicksort ( integer array v( * )
|
||||
; integer value lb, ub
|
||||
) ;
|
||||
if ub > lb then begin
|
||||
% more than one element, so must sort %
|
||||
integer left, right, pivot;
|
||||
left := lb;
|
||||
right := ub;
|
||||
% choosing the middle element of the array as the pivot %
|
||||
pivot := v( left + ( ( right + 1 ) - left ) div 2 );
|
||||
while begin
|
||||
while left <= ub and v( left ) < pivot do left := left + 1;
|
||||
while right >= lb and v( right ) > pivot do right := right - 1;
|
||||
left <= right
|
||||
end do begin
|
||||
integer swap;
|
||||
swap := v( left );
|
||||
v( left ) := v( right );
|
||||
v( right ) := swap;
|
||||
left := left + 1;
|
||||
right := right - 1
|
||||
end while_left_le_right ;
|
||||
quicksort( v, lb, right );
|
||||
quicksort( v, left, ub )
|
||||
end quicksort ;
|
||||
|
||||
% returns true if n is prime, false otherwise %
|
||||
logical procedure is_prime( integer value n ) ;
|
||||
if n < 2 then false
|
||||
else if n rem 2 = 0 then n = 2
|
||||
else if n rem 3 = 0 then n = 3
|
||||
else begin
|
||||
logical prime; prime := true;
|
||||
for f := 5 step 6 until entier( sqrt( n ) ) do begin
|
||||
if n rem f = 0 or n rem ( f + 2 ) = 0 then begin
|
||||
prime := false;
|
||||
goto done
|
||||
end if_n_rem_f_eq_0_or_n_rem_f_plus_2_eq_0
|
||||
end for_f;
|
||||
done: prime
|
||||
end is_prime ;
|
||||
|
||||
% increments n and also returns its new value %
|
||||
integer procedure inc ( integer value result n ) ; begin n := n + 1; n end;
|
||||
|
||||
% sets primes to the list of descending primes and lenPrimes to the %
|
||||
% number of descending primes - primes must be big enough, e.g. have 511 %
|
||||
% elements %
|
||||
procedure descending_primes ( integer array primes ( * )
|
||||
; integer result lenPrimes
|
||||
) ;
|
||||
begin
|
||||
integer array digits ( 1 :: 9 );
|
||||
integer array candidates ( 1 :: 6000 );
|
||||
integer lenCandidates;
|
||||
candidates( 1 ) := 0;
|
||||
lenCandidates := 1;
|
||||
lenPrimes := 0;
|
||||
for i := 1 until 9 do digits( i ) := 10 - i;
|
||||
for i := 1 until 9 do begin
|
||||
for j := 1 until lenCandidates do begin
|
||||
integer cValue; cValue := candidates( j ) * 10 + digits( i );
|
||||
if is_prime( cValue ) then primes( inc( lenPrimes ) ) := cValue;
|
||||
candidates( inc( lenCandidates ) ) := cValue
|
||||
end for_j
|
||||
end for_i ;
|
||||
quickSort( primes, 1, lenPrimes );
|
||||
end descending_primes ;
|
||||
|
||||
begin % find the descending primes and print them %
|
||||
integer array primes ( 1 :: 512 );
|
||||
integer lenPrimes;
|
||||
descending_primes( primes, lenPrimes );
|
||||
for i := 1 until lenPrimes do begin
|
||||
writeon( i_w := 8, s_w := 0, " ", primes( i ) );
|
||||
if i rem 10 = 0 then write()
|
||||
end for_i
|
||||
end
|
||||
end.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Multiplicative digital root
|
||||
fn mdroot(n: u32) -> (u32, u32) {
|
||||
let mut count = 0;
|
||||
let mut mdr = n;
|
||||
while mdr > 9 {
|
||||
let mut m = mdr;
|
||||
let mut digits_mul = 1;
|
||||
while m > 0 {
|
||||
digits_mul *= m % 10;
|
||||
m /= 10;
|
||||
}
|
||||
mdr = digits_mul;
|
||||
count += 1;
|
||||
}
|
||||
return (count, mdr);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Number: (MP, MDR)\n====== =========");
|
||||
for n in [123321, 7739, 893, 899998] {
|
||||
println!("{:6}: {:?}", n, mdroot(n));
|
||||
}
|
||||
let mut table = vec![vec![0_u32; 0]; 10];
|
||||
let mut n = 0;
|
||||
while table.iter().map(|row| row.len()).min().unwrap() < 5 {
|
||||
let (_, mdr) = mdroot(n);
|
||||
table[mdr as usize].push(n);
|
||||
n += 1;
|
||||
}
|
||||
println!("\nMDR First 5 with matching MDR\n=== =========================");
|
||||
table.sort();
|
||||
for a in table {
|
||||
println!("{:2}: {:5}{:6}{:6}{:6}{:6}", a[0], a[0], a[1], a[2], a[3], a[4]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
100 DEF FN MOD(NUM) = NUM - INT (NUM / DIV) * DIV: REM NUM MOD DIV
|
||||
110 M = 50:N = 4
|
||||
120 PRINT "FIRST "M" DUFFINIAN NUMBERS:"
|
||||
130 FOR C = 0 TO M STEP 0
|
||||
140 GOSUB 600"DUFF
|
||||
150 IF DUFF THEN PRINT RIGHT$ (" " + STR$ (N),4);:C = C + 1
|
||||
160 N = N + 1
|
||||
170 NEXT C
|
||||
180 M = 15:S = 4:M$ = CHR$ (13)
|
||||
190 PRINT M$M$"FIRST "M" DUFFINIAN TRIPLETS:"
|
||||
200 FOR C = 0 TO M STEP 0
|
||||
210 FOR D = 2 TO 0 STEP - 1:N = S + D: GOSUB 600: IF DUFF THEN NEXT D
|
||||
220 IF D < 0 THEN C = C + 1: PRINT RIGHT$ (" " + STR$ (S) + "-",5) LEFT$ ( STR$ (S + 2) + " ",5);:D = 0
|
||||
230 S = S + D + 1
|
||||
240 NEXT C
|
||||
250 END
|
||||
|
||||
REM ISPRIME V RETURNS ISPRIME
|
||||
260 ISPRIME = FALSE: IF V < 2 THEN RETURN
|
||||
270 DIV = 2:ISPRIME = FN MOD(V): IF NOT ISPRIME THEN ISPRIME = V = 2: RETURN
|
||||
280 LIMIT = SQR (V): IF LIMIT > = 3 THEN FOR DIV = 3 TO LIMIT STEP 2:ISPRIME = FN MOD(V): IF ISPRIME THEN NEXT DIV
|
||||
290 RETURN
|
||||
|
||||
REM GREATEST COMMON DIVISOR (GCD) A B RETURNS GCD
|
||||
300 A = ABS ( INT (A))
|
||||
310 B = ABS ( INT (B))
|
||||
320 GCD = A * NOT NOT B
|
||||
330 FOR B = B + A * NOT B TO 0 STEP 0
|
||||
340 A = GCD
|
||||
350 GCD = B
|
||||
360 B = A - INT (A / GCD) * GCD
|
||||
370 NEXT B
|
||||
380 RETURN
|
||||
|
||||
REM SUMDIV NUM RETURNS SUM
|
||||
400 DIV = 2
|
||||
410 SUM = 0
|
||||
420 QUOT = NUM / DIV
|
||||
430 IF DIV > QUOT THEN SUM = 1: RETURN
|
||||
440 FOR LOOP = 0 TO 1 STEP 0
|
||||
450 IF FN MOD(NUM) = 0 THEN SUM = SUM + DIV: IF DIV < > QUOT THEN SUM = SUM + QUOT
|
||||
460 DIV = DIV + 1
|
||||
470 QUOT = NUM / DIV
|
||||
480 LOOP = DIV > QUOT
|
||||
500 NEXT LOOP
|
||||
510 SUM = SUM + 1
|
||||
520 RETURN
|
||||
|
||||
REM DUFF N RETURNS DUFF
|
||||
600 DUFF = FALSE
|
||||
610 V = N: GOSUB 260"ISPRIME
|
||||
620 IF ISPRIME THEN RETURN
|
||||
630 NUM = N: GOSUB 400"SUMDIV
|
||||
640 A = SUM:B = N: GOSUB 300"GCD
|
||||
650 DUFF = GCD = 1
|
||||
660 RETURN
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
use gcd::Gcd;
|
||||
|
||||
fn ekg_sequence(n: u64, limit: usize) -> Vec<u64> {
|
||||
let mut ekg = [1_u64, n].to_vec();
|
||||
while ekg.len() < limit {
|
||||
for i in 2..2<<18 {
|
||||
if ekg.iter().all(|j| *j != i) && Gcd::gcd(ekg[ekg.len()-1], i) > 1 {
|
||||
ekg.push(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ekg;
|
||||
}
|
||||
|
||||
|
||||
fn converge_at(n: u64, m: u64, tmax: usize) -> usize {
|
||||
let a = ekg_sequence(n, tmax);
|
||||
let b = ekg_sequence(m, tmax);
|
||||
for i in 2..tmax {
|
||||
if a[i] == b[i] && a[0..i+1].iter().sum::<u64>() == (b[0..i+1]).iter().sum::<u64>() {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
println!("Error: no convergence in {tmax} terms");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for i in [2_u64, 5, 7, 9, 10] {
|
||||
println!("EKG({i:2}): {:?}", ekg_sequence(i, 30_usize));
|
||||
}
|
||||
println!("EKGs of 5 & 7 converge after term {:?}", converge_at(5, 7, 50));
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
public final class ElementaryCellularAutomatonInfiniteLength {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
evolve(35, 90);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static void evolve(int aLimit, int aRule) {
|
||||
System.out.println(" Rule# " + aRule);
|
||||
StringBuilder cells = new StringBuilder(Character.toString(STAR));
|
||||
for ( int i = 0; i < aLimit; i++ ) {
|
||||
addCells(cells);
|
||||
final int width = 40 - ( cells.length() >> 1 );
|
||||
System.out.println(" ".repeat(width) + cells);
|
||||
cells = nextStep(cells, aRule);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addCells(StringBuilder aCells) {
|
||||
final char left = ( aCells.charAt(0) == STAR ) ? DOT : STAR;
|
||||
final char right = ( aCells.charAt(aCells.length() - 1 ) == STAR ) ? DOT : STAR;
|
||||
for ( int i = 0; i < 2; i++ ) {
|
||||
aCells.insert(0, left);
|
||||
aCells.append(right);
|
||||
}
|
||||
}
|
||||
|
||||
private static StringBuilder nextStep(StringBuilder aCells, int aRule) {
|
||||
StringBuilder nextCells = new StringBuilder();
|
||||
for ( int i = 0; i < aCells.length() - 2; i++ ) {
|
||||
int binary = 0;
|
||||
int shift = 2;
|
||||
for ( int j = i; j < i + 3; j++ ) {
|
||||
binary += ( ( aCells.charAt(j) == STAR ) ? 1 : 0 ) << shift;
|
||||
shift >>= 1;
|
||||
}
|
||||
final char symbol = ( ( aRule & ( 1 << binary ) ) == 0 ) ? DOT : STAR;
|
||||
nextCells.append(symbol);
|
||||
}
|
||||
return nextCells;
|
||||
}
|
||||
|
||||
private static final char DOT = '.';
|
||||
private static final char STAR = '*';
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[[wp:Rule 30|Rule 30]] is considered to be chaotic enough to generate good pseudo-random numbers. As a matter of fact, rule 30 is used by the [[wp:Mathematica|Mathematica]] software for its default random number generator.
|
||||
[[wp:Rule 30|Rule 30]] is considered to be chaotic enough to generate good pseudo-random numbers. As a matter of fact, for a long time rule 30 was used by the [[wp:Mathematica|Mathematica]] software for its default random number generator.
|
||||
|
||||
Steven Wolfram's recommendation for random number generation from rule 30 consists in extracting successive bits in a fixed position in the array of cells, as the automaton changes state.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
public class ElementaryCellularAutomatonRandomNumberGenerator {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
final int seed = 989898989;
|
||||
evolve(seed, 30);
|
||||
}
|
||||
|
||||
private static void evolve(int aState, int aRule) {
|
||||
long state = aState;
|
||||
for ( int i = 0; i <= 9; i++ ) {
|
||||
int b = 0;
|
||||
for ( int q = 7; q >= 0; q-- ) {
|
||||
long stateCopy = state;
|
||||
b |= ( stateCopy & 1 ) << q;
|
||||
state = 0;
|
||||
for ( int j = 0; j < BIT_COUNT; j++ ) {
|
||||
long t = ( stateCopy >>> ( j - 1 ) ) | ( stateCopy << ( BIT_COUNT + 1 - j ) ) & 7;
|
||||
if ( ( aRule & ( 1L << t ) ) != 0 ) {
|
||||
state |= 1 << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.print(" " + b);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static final int BIT_COUNT = 64;
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
class Automaton {
|
||||
has $.rule;
|
||||
has @.cells;
|
||||
has @.cells handles <AT-POS>;
|
||||
has @.code = $!rule.fmt('%08b').flip.comb».Int;
|
||||
|
||||
method gist { "|{ @!cells.map({+$_ ?? '#' !! ' '}).join }|" }
|
||||
|
|
@ -18,4 +18,4 @@ class Automaton {
|
|||
|
||||
my Automaton $a .= new: :rule(30), :cells( flat 1, 0 xx 100 );
|
||||
|
||||
say :2[$a++.cells[0] xx 8] xx 10;
|
||||
say :2[$a++[0] xx 8] xx 10;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
import java.util.BitSet;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class EqualPrimeAndCompositeSums {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
PrimeIterator primeIterator = new PrimeIterator();
|
||||
CompositeIterator compositeIterator = new CompositeIterator();
|
||||
long primeSum = primeIterator.next();
|
||||
long compositeSum = compositeIterator.next();
|
||||
int primeIndex = 1;
|
||||
int compositeIndex = 1;
|
||||
|
||||
System.out.println("Sum | Prime Index | Composite Index");
|
||||
System.out.println("----------------------------------------------");
|
||||
int count = 0;
|
||||
while ( count < 8 ) {
|
||||
if ( primeSum == compositeSum ) {
|
||||
System.out.println(String.format("%13d%s%12d%s%15d",
|
||||
primeSum, " | ", primeIndex, " | ", compositeIndex));
|
||||
|
||||
primeSum += primeIterator.next();
|
||||
primeIndex += 1;
|
||||
compositeSum += compositeIterator.next();
|
||||
compositeIndex += 1;
|
||||
count += 1;
|
||||
} else if ( primeSum < compositeSum ) {
|
||||
primeSum += primeIterator.next();
|
||||
primeIndex += 1;
|
||||
} else {
|
||||
compositeSum += compositeIterator.next();
|
||||
compositeIndex += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CompositeIterator {
|
||||
|
||||
public CompositeIterator() {
|
||||
primeIterator = new PrimeIterator();
|
||||
prime = primeIterator.next();
|
||||
composite = prime;
|
||||
while ( composite == prime ) {
|
||||
prime = primeIterator.next();
|
||||
composite += 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int next() {
|
||||
final int result = composite;
|
||||
while ( ++composite == prime ) {
|
||||
prime = primeIterator.next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int prime, composite;
|
||||
private PrimeIterator primeIterator;
|
||||
|
||||
}
|
||||
|
||||
private static class PrimeIterator {
|
||||
|
||||
public PrimeIterator() {
|
||||
if ( Objects.isNull(sieve) ) {
|
||||
listPrimeNumbers(10_000_000);
|
||||
}
|
||||
}
|
||||
|
||||
public int next() {
|
||||
if ( lastPrime < sieve.cardinality() ) {
|
||||
lastPrime = sieve.nextSetBit(lastPrime + 1);
|
||||
} else {
|
||||
do {
|
||||
lastPrime += 2;
|
||||
}
|
||||
while ( ! isPrime(lastPrime) );
|
||||
}
|
||||
return lastPrime;
|
||||
}
|
||||
|
||||
private static boolean isPrime(int aCandidate) {
|
||||
for ( int i = 2; i <= Math.sqrt(aCandidate); i = sieve.nextSetBit(i + 1) ) {
|
||||
if ( aCandidate % i == 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void listPrimeNumbers(int aN) {
|
||||
sieve = new BitSet(aN + 1);
|
||||
sieve.set(2, aN + 1);
|
||||
for ( int i = 2; i <= Math.sqrt(aN); i = sieve.nextSetBit(i + 1) ) {
|
||||
for ( int j = i * i; j <= aN; j = j + i ) {
|
||||
sieve.clear(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int lastPrime;
|
||||
private static BitSet sieve;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,17 +4,16 @@ import java.util.BitSet;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class EulerMullinSequence {
|
||||
public final class EulerMullinSequence {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
primes = listPrimesUpTo(1_000_000);
|
||||
|
||||
System.out.println("The first 27 terms of the Euler-Mullin sequence:");
|
||||
System.out.println(2);
|
||||
System.out.print(2 + " ");
|
||||
for ( int i = 1; i < 27; i++ ) {
|
||||
System.out.println(nextEulerMullin());
|
||||
System.out.print(String.format("%s%s", nextEulerMullin(), ( i == 14 || i == 27 ) ? "\n" : " "));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static BigInteger nextEulerMullin() {
|
||||
|
|
@ -25,7 +24,7 @@ public class EulerMullinSequence {
|
|||
}
|
||||
|
||||
private static BigInteger smallestPrimeFactor(BigInteger aNumber) {
|
||||
if ( aNumber.isProbablePrime(probabilityLevel) ) {
|
||||
if ( aNumber.isProbablePrime(CERTAINTY_LEVEL) ) {
|
||||
return aNumber;
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +85,6 @@ public class EulerMullinSequence {
|
|||
private static BigInteger product = BigInteger.TWO;
|
||||
private static ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
|
||||
private static final int probabilityLevel = 20;
|
||||
private static final int CERTAINTY_LEVEL = 20;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
(if (even? some-var) (do-even-stuff))
|
||||
(if (odd? some-var) (do-odd-stuff))
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
sub fibonacci {
|
||||
my $n = shift;
|
||||
|
||||
return 0 if $n < 1;
|
||||
return 1 if $n == 1;
|
||||
|
||||
my @numbers = (0, 1);
|
||||
|
||||
push @numbers, $numbers[-1] + $numbers[-2] foreach 2 .. $n;
|
||||
|
||||
return $numbers[-1];
|
||||
}
|
||||
|
||||
print "Fibonacci($_) -> ", (fibonacci $_), "\n"
|
||||
foreach (0 .. 20, 50, 93, 94, 100, 200, 1000, 1476, 1477);
|
||||
|
|
@ -3,8 +3,8 @@
|
|||
r/o open-file throw >r
|
||||
w/o create-file throw r>
|
||||
begin
|
||||
pad maxstring 2 pick read-file throw
|
||||
?dup while
|
||||
pad 84 2 pick read-file throw
|
||||
?dup while
|
||||
pad swap 3 pick write-file throw
|
||||
repeat
|
||||
close-file throw
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class FileSizeDistribution {
|
||||
|
||||
public static void main(String[] aArgs) throws IOException {
|
||||
List<Path> fileNames = Files.list(Path.of("."))
|
||||
.filter( file -> ! Files.isDirectory(file) )
|
||||
.map(Path::getFileName)
|
||||
.toList();
|
||||
|
||||
Map<Integer, Integer> fileSizes = new HashMap<Integer, Integer>();
|
||||
for ( Path path : fileNames ) {
|
||||
fileSizes.merge(String.valueOf(Files.size(path)).length(), 1, Integer::sum);
|
||||
}
|
||||
|
||||
final int fileCount = fileSizes.values().stream().mapToInt(Integer::valueOf).sum();
|
||||
|
||||
System.out.println("File size distribution for directory \".\":" + System.lineSeparator());
|
||||
System.out.println("File size in bytes | Number of files | Percentage");
|
||||
System.out.println("-------------------------------------------------");
|
||||
for ( int key : fileSizes.keySet() ) {
|
||||
final int value = fileSizes.get(key);
|
||||
System.out.println(String.format("%s%d%s%d%15d%15.1f%%",
|
||||
" 10^", ( key - 1 ), " to 10^", key, value, ( 100.0 * value ) / fileCount));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
const std::set<std::pair<char, int32_t>> correct_pieces = { std::make_pair('R', 2), std::make_pair('N', 2),
|
||||
std::make_pair('B', 2), std::make_pair('Q', 1), std::make_pair('K', 1) };
|
||||
|
||||
std::map<std::vector<int32_t>, int32_t> knights_table = {
|
||||
{ std::vector<int32_t>{ 0, 1 }, 0 },
|
||||
{ std::vector<int32_t>{ 0, 2 }, 1 },
|
||||
{ std::vector<int32_t>{ 0, 3 }, 2 },
|
||||
{ std::vector<int32_t>{ 0, 4 }, 3 },
|
||||
{ std::vector<int32_t>{ 1, 2 }, 4 },
|
||||
{ std::vector<int32_t>{ 1, 3 }, 5 },
|
||||
{ std::vector<int32_t>{ 1, 4 }, 6 },
|
||||
{ std::vector<int32_t>{ 2, 3 }, 7 },
|
||||
{ std::vector<int32_t>{ 2, 4 }, 8 },
|
||||
{ std::vector<int32_t>{ 3, 4 }, 9 } };
|
||||
|
||||
void validate(const std::string& position) {
|
||||
if ( position.length() != 8 ) {
|
||||
throw std::invalid_argument("Chess position has invalid length" + std::to_string(position.length()));
|
||||
}
|
||||
|
||||
std::map<char, int32_t> position_map;
|
||||
for ( const char& ch : position ) {
|
||||
if ( position_map.find(ch) == position_map.end() ) {
|
||||
position_map.emplace(ch, 1);
|
||||
} else {
|
||||
position_map[ch]++;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::pair<char, int32_t>> pieces;
|
||||
std::transform(position_map.begin(), position_map.end(), std::inserter(pieces, pieces.begin()),
|
||||
[](const std::pair<char, int32_t>& entry) { return entry; });
|
||||
|
||||
if ( pieces != correct_pieces ) {
|
||||
throw std::invalid_argument("Chess position contains incorrect pieces.");
|
||||
}
|
||||
|
||||
const std::vector<uint64_t> bishops = { position.find_first_of('B'), position.find_last_of('B') };
|
||||
if ( ( bishops[1] - bishops[0] ) % 2 == 0 ) {
|
||||
throw std::invalid_argument("Bishops must be on different coloured squares.");
|
||||
}
|
||||
|
||||
std::vector<uint64_t> rook_king =
|
||||
{ position.find_first_of('R'), position.find_first_of('K'), position.find_last_of('R') };
|
||||
if ( ! ( rook_king[0] < rook_king[1] && rook_king[1] < rook_king[2] ) ) {
|
||||
throw std::invalid_argument("The king must be between the two rooks.");
|
||||
}
|
||||
}
|
||||
|
||||
int32_t calculate_SPID(std::string& position) {
|
||||
|
||||
const int32_t index_one = position.find_first_of('B');
|
||||
const int32_t index_two = position.find_last_of('B');
|
||||
const int32_t D = ( index_one % 2 == 0 ) ? index_one / 2 : index_two / 2;
|
||||
const int32_t L = ( index_one % 2 == 0 ) ? index_two / 2 : index_one / 2;
|
||||
|
||||
position.erase(remove_if(position.begin(), position.end(),
|
||||
[](const char& ch){ return ch == 'B'; }), position.end());
|
||||
const uint64_t Q = position.find_first_of('Q');
|
||||
|
||||
position.erase(remove_if(position.begin(), position.end(),
|
||||
[](const char& ch){ return ch == 'Q'; }), position.end());
|
||||
const int32_t N =
|
||||
knights_table[ { (int32_t) position.find_first_of('N'), (int32_t) position.find_last_of('N') } ];
|
||||
|
||||
return 96 * N + 16 * Q + 4 * D + L;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::vector<std::string> positions = { "QNRBBNKR", "RNBQKBNR", "RQNBBKRN", "RNQBBKRN" };
|
||||
|
||||
for ( std::string& position : positions ) {
|
||||
validate(position);
|
||||
std::cout << "Position " << position << " has Chess960 SP-ID = " << calculate_SPID(position) << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,9 +10,10 @@ public final class Chess960SPID {
|
|||
String[] positions = { "QNRBBNKR", "RNBQKBNR", "RQNBBKRN", "RNQBBKRN" };
|
||||
|
||||
createKnightsTable();
|
||||
createCorrectPieces();
|
||||
|
||||
for ( String position : positions ) {
|
||||
validate("RQNBBKRN");
|
||||
validate(position);
|
||||
System.out.println("Position " + position + " has Chess960 SP-ID = " + calculateSPID(position));
|
||||
}
|
||||
}
|
||||
|
|
@ -26,8 +27,7 @@ public final class Chess960SPID {
|
|||
for ( char ch : aPosition.toCharArray() ) {
|
||||
pieces.merge(ch, 1, (oldV, newV) -> oldV + 1);
|
||||
}
|
||||
Set<Map.Entry<Character, Integer>> correctPieces =
|
||||
Set.of(Map.entry('R', 2), Map.entry('N', 2), Map.entry('B', 2), Map.entry('Q', 1), Map.entry('K', 1));
|
||||
|
||||
if ( ! pieces.entrySet().equals(correctPieces) ) {
|
||||
throw new AssertionError("Chess position contains incorrect pieces.");
|
||||
}
|
||||
|
|
@ -78,8 +78,14 @@ public final class Chess960SPID {
|
|||
knightsTable.put(List.of(2, 3), 7);
|
||||
knightsTable.put(List.of(2, 4), 8);
|
||||
knightsTable.put(List.of(3, 4), 9);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createCorrectPieces() {
|
||||
correctPieces = Set.of(
|
||||
Map.entry('R', 2), Map.entry('N', 2), Map.entry('B', 2), Map.entry('Q', 1), Map.entry('K', 1) );
|
||||
}
|
||||
|
||||
private static Map<List<Integer>, Integer> knightsTable;
|
||||
private static Set<Map.Entry<Character, Integer>> correctPieces;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
// Convert the given decimal number to the given number base
|
||||
// and return it converted to a string
|
||||
std::string to_base_string(const uint64_t& number, const uint32_t& base) {
|
||||
uint64_t n = number;
|
||||
if ( n == 0 ) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
std::string result;
|
||||
while ( n > 0 ) {
|
||||
result += std::to_string(n % base);
|
||||
n /= base;
|
||||
}
|
||||
std::reverse(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
void display(const uint64_t& number) {
|
||||
std::cout << "Decimal: " << number << std::endl;
|
||||
std::cout << "Binary : " << to_base_string(number, 2) << std::endl;
|
||||
std::cout << "Ternary: " << to_base_string(number, 3) << std::endl << std::endl;
|
||||
}
|
||||
|
||||
bool is_palindromic(const std::string& number) {
|
||||
std::string copy = number;
|
||||
std::reverse(copy.begin(), copy.end());
|
||||
return number == copy;
|
||||
}
|
||||
|
||||
// Create a ternary palindrome whose left part is the ternary equivalent of the given number
|
||||
// and return it converted to a decimal
|
||||
uint64_t create_ternary_palindrome(const uint64_t& number) {
|
||||
std::string ternary = to_base_string(number, 3);
|
||||
uint64_t power_of_3 = 1;
|
||||
uint64_t result = 0;
|
||||
for ( uint64_t i = 0; i < ternary.length(); ++i ) { // Right part of palindrome is the mirror image of left part
|
||||
if ( ternary[i] > '0' ) {
|
||||
result += ( ternary[i] - '0' ) * power_of_3;
|
||||
}
|
||||
power_of_3 *= 3;
|
||||
}
|
||||
result += power_of_3; // Middle digit must be 1
|
||||
power_of_3 *= 3;
|
||||
result += number * power_of_3; // Left part is the given number multiplied by the appropriate power of 3
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "The first 6 numbers which are palindromic in both binary and ternary are:" << std::endl;
|
||||
display(0); // 0 is a palindrome in all 3 bases
|
||||
display(1); // 1 is a palindrome in all 3 bases
|
||||
|
||||
uint64_t number = 1;
|
||||
uint32_t count = 2;
|
||||
do {
|
||||
uint64_t ternary = create_ternary_palindrome(number);
|
||||
if ( ternary % 2 == 1 ) { // Cannot be an even number since its binary equivalent would end in zero
|
||||
std::string binary = to_base_string(ternary, 2);
|
||||
if ( binary.length() % 2 == 1 ) { // Binary palindrome must have an odd number of digits
|
||||
if ( is_palindromic(binary) ) {
|
||||
display(ternary);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
number++;
|
||||
}
|
||||
while ( count < 6 );
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
public final class FindPalindromicNumbersBases23 {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
System.out.println("The first 7 numbers which are palindromic in both binary and ternary are:");
|
||||
display(0); // 0 is a palindrome in all 3 bases
|
||||
display(1); // 1 is a palindrome in all 3 bases
|
||||
|
||||
long number = 1;
|
||||
int count = 2;
|
||||
do {
|
||||
long ternary = createTernaryPalindrome(number);
|
||||
if ( ternary % 2 == 1 ) { // Cannot be an even number since its binary equivalent would end in zero
|
||||
String binary = toBinaryString(ternary);
|
||||
if ( binary.length() % 2 == 1 ) { // Binary palindrome must have an odd number of digits
|
||||
if ( isPalindromic(binary) ) {
|
||||
display(ternary);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
number++;
|
||||
}
|
||||
while ( count < 7 );
|
||||
}
|
||||
|
||||
// Create a ternary palindrome whose left part is the ternary equivalent of the given number
|
||||
// and return its decimal equivalent
|
||||
private static long createTernaryPalindrome(long aNumber) {
|
||||
String ternary = toTernaryString(aNumber);
|
||||
long powerOf3 = 1;
|
||||
long sum = 0;
|
||||
for ( int i = 0; i < ternary.length(); i++ ) { // Right part of a palindrome is the mirror image of left part
|
||||
if ( ternary.charAt(i) > '0' ) {
|
||||
sum += ( ternary.charAt(i) - '0' ) * powerOf3;
|
||||
}
|
||||
powerOf3 *= 3;
|
||||
}
|
||||
sum += powerOf3; // Middle digit must be 1
|
||||
powerOf3 *= 3;
|
||||
sum += aNumber * powerOf3; // Left part is the given number multiplied by the appropriate power of 3
|
||||
return sum;
|
||||
}
|
||||
|
||||
private static boolean isPalindromic(String aNumber) {
|
||||
return aNumber.equals( new StringBuilder(aNumber).reverse().toString() );
|
||||
}
|
||||
|
||||
private static String toTernaryString(long aNumber) {
|
||||
if ( aNumber == 0 ) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
while ( aNumber > 0 ) {
|
||||
result.append(aNumber % 3);
|
||||
aNumber /= 3;
|
||||
}
|
||||
return result.reverse().toString();
|
||||
}
|
||||
|
||||
private static String toBinaryString(long aNumber) {
|
||||
return Long.toBinaryString(aNumber);
|
||||
}
|
||||
|
||||
private static void display(long aNumber) {
|
||||
System.out.println("Decimal: " + aNumber);
|
||||
System.out.println("Binary : " + toBinaryString(aNumber));
|
||||
System.out.println("Ternary: " + toTernaryString(aNumber));
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "The dates of the last Sunday in each month of 2023:" << std::endl;
|
||||
|
||||
for ( unsigned int m = 1; m <= 12; ++m ) {
|
||||
std::chrono::days days_in_month = std::chrono::sys_days{std::chrono::year{2023}/m/std::chrono::last}
|
||||
- std::chrono::sys_days{std::chrono::year{2023}/m/1} + std::chrono::days{1};
|
||||
|
||||
const unsigned int last_day = days_in_month / std::chrono::days{1};
|
||||
std::chrono::year_month_day ymd{std::chrono::year{2023}, std::chrono::month{m}, std::chrono::day{last_day}};
|
||||
|
||||
while ( std::chrono::weekday{ymd} != std::chrono::Sunday ) {
|
||||
ymd = std::chrono::sys_days{ymd} - std::chrono::days{1};
|
||||
}
|
||||
|
||||
std::cout << ymd << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main() {
|
||||
const std::vector<std::chrono::month> long_months = { std::chrono::January, std::chrono::March,
|
||||
std::chrono::May, std::chrono::July, std::chrono::August, std::chrono::October, std::chrono::December };
|
||||
|
||||
int month_count = 0;
|
||||
int blank_years = 0;
|
||||
for ( int y = 1900; y <= 2100; ++y ) {
|
||||
bool blank_year = true;
|
||||
for ( std::chrono::month m : long_months ) {
|
||||
std::chrono::year_month_day first_of_month{std::chrono::year{y}, m, std::chrono::day{1}};
|
||||
if ( std::chrono::weekday{first_of_month} == std::chrono::Friday ) {
|
||||
std::cout << first_of_month.year() << " " << first_of_month.month() << std::endl;
|
||||
month_count++;
|
||||
blank_year = false;
|
||||
}
|
||||
}
|
||||
if ( blank_year ) {
|
||||
blank_years++;
|
||||
}
|
||||
}
|
||||
std::cout << "Found " << month_count << " months with five Fridays, Saturdays and Sundays." << std::endl;
|
||||
std::cout << "There were " << blank_years << " years with no such months." << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
(3‿5 (0=|)◶[⊢‿"fizz","buzz"‿"fizzbuzz"] ⊢)¨ 1+↕100
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
(function fizzbuzz n
|
||||
(match (map (rem n) [3 5])
|
||||
[0 0] "FizzBuzz"
|
||||
[0 _] "Fizz"
|
||||
[_ 0] "Buzz"
|
||||
n))
|
||||
|
||||
(loop 100 i
|
||||
(-> i inc fizzbuzz print))
|
||||
|
|
@ -1,20 +1,16 @@
|
|||
#!/usr/bin/env luajit
|
||||
local to=arg[1] or tonumber(arg[1]) or 100
|
||||
local CF,CB=3,5
|
||||
local cf,cb=CF,CB
|
||||
for i=1,to do
|
||||
cf,cb=cf-1,cb-1
|
||||
if cf~=0 and cb~=0 then
|
||||
io.write(i)
|
||||
else
|
||||
if cf==0 then
|
||||
cf=CF
|
||||
io.write("Fizz")
|
||||
end
|
||||
if cb==0 then
|
||||
cb=CB
|
||||
io.write("Buzz")
|
||||
end
|
||||
end
|
||||
io.write(", ")
|
||||
end
|
||||
local mt = {
|
||||
__newindex = (function (t, k, v)
|
||||
if type(k) ~= "number" then rawset(t, k, v)
|
||||
elseif 0 == (k % 15) then rawset(t, k, "fizzbuzz")
|
||||
elseif 0 == (k % 5) then rawset(t, k, "fizz")
|
||||
elseif 0 == (k % 3) then rawset(t, k, "buzz")
|
||||
else rawset(t, k, k) end
|
||||
return t[k]
|
||||
end)
|
||||
}
|
||||
|
||||
local fizzbuzz = {}
|
||||
setmetatable(fizzbuzz, mt)
|
||||
|
||||
for i=1,100 do fizzbuzz[i] = i end
|
||||
for i=1,100 do print(fizzbuzz[i]) end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env luajit
|
||||
local to=arg[1] or tonumber(arg[1]) or 100
|
||||
local CF,CB=3,5
|
||||
local cf,cb=CF,CB
|
||||
for i=1,to do
|
||||
cf,cb=cf-1,cb-1
|
||||
if cf~=0 and cb~=0 then
|
||||
io.write(i)
|
||||
else
|
||||
if cf==0 then
|
||||
cf=CF
|
||||
io.write("Fizz")
|
||||
end
|
||||
if cb==0 then
|
||||
cb=CB
|
||||
io.write("Buzz")
|
||||
end
|
||||
end
|
||||
io.write(", ")
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
local phi, phi0, expected, iters = 1, 0, (1 + math.sqrt(5)) / 2, 0
|
||||
repeat
|
||||
phi0, phi = phi, 1 + 1 / phi
|
||||
iters = iters + 1
|
||||
until math.abs(phi0 - phi) < 1e-5
|
||||
io.write( "after ", iters, " iterations, phi = ", phi )
|
||||
io.write( ", expected value: ", expected, ", diff: ", math.abs( expected - phi ), "\n" )
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# 20230719 Raku programming solution
|
||||
|
||||
my \factorials = 1, | [\*] 1..18; # with 0!
|
||||
|
||||
sub JordanPolya (\limit) {
|
||||
my \ix = (factorials.keys.first: factorials[*] >= limit) // factorials.end;
|
||||
my ($k, @res) = 2, |factorials[0..ix];
|
||||
|
||||
while $k < @res.elems {
|
||||
my \rk = @res[$k];
|
||||
for 2 .. @res.elems -> \l {
|
||||
my \kl = $ = @res[l] * rk;
|
||||
last if kl > limit;
|
||||
loop {
|
||||
my \p = @res.keys.first: { @res[$_] >= kl } # performance
|
||||
if p < @res.elems and @res[p] != kl {
|
||||
@res = |@res[^p], kl, |@res[p..*]
|
||||
} elsif p == @res.elems {
|
||||
@res.append: kl
|
||||
}
|
||||
kl > limit/rk ?? ( last ) !! kl *= rk
|
||||
}
|
||||
}
|
||||
$k++
|
||||
}
|
||||
return @res[1..*]
|
||||
}
|
||||
|
||||
my @result = JordanPolya 2**30 ;
|
||||
say "First 50 Jordan-Pólya numbers:";
|
||||
say [~] $_>>.fmt('%5s') for @result[^50].rotor(10);
|
||||
print "\nThe largest Jordan-Pólya number before 100 million: ";
|
||||
say @result.first: * < 100_000_000, :end;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "The dates of the last Friday in each month of 2023:" << std::endl;
|
||||
|
||||
for ( unsigned int m = 1; m <= 12; ++m ) {
|
||||
std::chrono::days days_in_month = std::chrono::sys_days{std::chrono::year{2023}/m/std::chrono::last}
|
||||
- std::chrono::sys_days{std::chrono::year{2023}/m/1} + std::chrono::days{1};
|
||||
|
||||
const unsigned int last_day = days_in_month / std::chrono::days{1};
|
||||
std::chrono::year_month_day ymd{std::chrono::year{2023}, std::chrono::month{m}, std::chrono::day{last_day}};
|
||||
|
||||
while ( std::chrono::weekday{ymd} != std::chrono::Friday ) {
|
||||
ymd = std::chrono::sys_days{ymd} - std::chrono::days{1};
|
||||
}
|
||||
|
||||
std::cout << ymd << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
(function look-and-say n x
|
||||
(return-when (empty? n) x)
|
||||
(var digit (0 n)
|
||||
[before after] ((juxt take-while skip-while) (= digit) n))
|
||||
(recur after (strn x (len before) digit)))
|
||||
|
||||
(var result "1")
|
||||
(loop 10 i
|
||||
(print (var! result look-and-say)))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
REM DEFINE THE ARRAYS AND POPULATE THEM
|
||||
0 SIZE = 3: DIM A$(SIZE),B$(SIZE),C(SIZE): FOR I = 1 TO SIZE:A$(I) = CHR$ (96 + I):B$(I) = CHR$ (64 + I):C(I) = I: NEXT
|
||||
|
||||
REM LOOP OVER MULTIPLE ARRAYS SIMULTANEOUSLY
|
||||
1 FOR I = 1 TO SIZE
|
||||
2 PRINT A$(I)B$(I)C(I)
|
||||
3 NEXT I
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(map str "abc" "ABC" "123")
|
||||
["aA1" "bB2" "cC3"]
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(map str ["a" "b" "c"] ["A" "B" "C"] ["1" "2" "3"])
|
||||
["aA1" "bB2" "cC3"]
|
||||
|
|
@ -13,7 +13,7 @@ columns
|
|||
120 IF l <= szb THEN READ b$(l): PRINT b$(l);
|
||||
130 IF l <= szc THEN READ c$(l): PRINT c$(l);
|
||||
140 PRINT: REM newline
|
||||
150 NEXT l
|
||||
145 NEXT l
|
||||
150 PRINT "The arrays are shown in columns."
|
||||
160 PRINT "A$ runs down the left hand side,"
|
||||
170 PRINT "and C$ runs down the right."
|
||||
|
|
|
|||
|
|
@ -4,39 +4,32 @@ gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
|
|||
d, h = 800, 500 # pixel density (= image width) and image height
|
||||
n, r = 200, 500 # number of iterations and escape radius (r > 2)
|
||||
|
||||
direction, height = 45, 1.5 # direction and height of the incoming light
|
||||
stripes, damping = 4, 2.0 # stripe density and damping parameter
|
||||
|
||||
x = range(0, 2, length=d+1)
|
||||
y = range(0, 2 * h / d, length=h+1)
|
||||
|
||||
A, B = collect(x) .- 1, collect(y) .- h / d
|
||||
C = (2.0 + 1.0im) .* (A' .+ B .* im) .- 0.5
|
||||
C = 2.0 .* (A' .+ B .* im) .- 0.5
|
||||
|
||||
Z, dZ, ddZ = zero(C), zero(C), zero(C)
|
||||
Z, dZ = zero(C), zero(C)
|
||||
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C))
|
||||
|
||||
for k in 1:n
|
||||
M = abs.(Z) .< r
|
||||
S[M], T[M] = S[M] .+ cos.(stripes .* angle.(Z[M])), T[M] .+ 1
|
||||
Z[M], dZ[M], ddZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1, 2 .* (dZ[M] .^ 2 .+ Z[M] .* ddZ[M])
|
||||
S[M], T[M] = S[M] .+ exp.(.- abs.(Z[M])), T[M] .+ 1
|
||||
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1
|
||||
end
|
||||
|
||||
N = abs.(Z) .>= r # normal map effect 1 (potential function)
|
||||
P, Q = S[N] ./ T[N], (S[N] .+ cos.(stripes .* angle.(Z[N]))) ./ (T[N] .+ 1)
|
||||
F = log2.(log.(abs.(Z[N])) ./ log(r)) # fraction between 0 and 1 (for interpolation)
|
||||
R = Q .+ (P .- Q) .* F .* F .* (3 .- 2 .* F) # hermite interpolation (r is between q and p)
|
||||
U, H = Z[N] ./ dZ[N], 1 .+ R ./ damping # normal vectors to the equipotential lines and height perturbation
|
||||
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and vector in light direction
|
||||
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ H .* height) ./ (1 + height), 0)
|
||||
heatmap(S .^ 0.1, c=:balance)
|
||||
savefig("Mandelbrot_set_1.png")
|
||||
|
||||
heatmap(D .^ 1.0, c=:bone_1)
|
||||
savefig("Mandelbrot_normal_map_1.png")
|
||||
N = abs.(Z) .>= r # normalized iteration count
|
||||
T[N] = T[N] .- log2.(log.(abs.(Z[N])) ./ log(r))
|
||||
|
||||
N = abs.(Z) .>= r # normal map effect 2 (distance estimation)
|
||||
U = Z[N] .* dZ[N] .* ((1 .+ log.(abs.(Z[N]))) .* conj.(dZ[N] .^ 2) .- log.(abs.(Z[N])) .* conj.(Z[N] .* ddZ[N]))
|
||||
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors and vector in light direction
|
||||
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0)
|
||||
heatmap(T .^ 0.1, c=:balance)
|
||||
savefig("Mandelbrot_set_2.png")
|
||||
|
||||
heatmap(D .^ 1.0, c=:afmhot)
|
||||
savefig("Mandelbrot_normal_map_2.png")
|
||||
N = abs.(Z) .> 2 # exterior distance estimation
|
||||
D[N] = 0.5 .* log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N])
|
||||
|
||||
heatmap(D .^ 0.1, c=:balance)
|
||||
savefig("Mandelbrot_set_3.png")
|
||||
|
|
|
|||
|
|
@ -1,39 +1,41 @@
|
|||
using Plots
|
||||
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
|
||||
|
||||
d, h = 200, 1200 # pixel density (= image width) and image height
|
||||
n, r = 8000, 10000 # number of iterations and escape radius (r > 2)
|
||||
d, h = 800, 500 # pixel density (= image width) and image height
|
||||
n, r = 200, 500 # number of iterations and escape radius (r > 2)
|
||||
|
||||
a = -.743643887037158704752191506114774 # real coordinate of the zoom center
|
||||
b = 0.131825904205311970493132056385139 # imaginary coordinate of the center
|
||||
direction, height = 45, 1.5 # direction and height of the incoming light
|
||||
stripes, damping = 4.0, 2.0 # stripe density and damping parameter
|
||||
|
||||
x = range(0, 2, length=d+1)
|
||||
y = range(0, 2 * h / d, length=h+1)
|
||||
|
||||
A, B = collect(x) .* pi, collect(y) .* pi
|
||||
C = 8.0 .* exp.((A' .+ B .* im) .* im) .+ (a + b * im)
|
||||
A, B = collect(x) .- 1, collect(y) .- h / d
|
||||
C = (2.0 + 1.0im) .* (A' .+ B .* im) .- 0.5
|
||||
|
||||
Z, dZ = zero(C), zero(C)
|
||||
D = zeros(size(C))
|
||||
Z, dZ, ddZ = zero(C), zero(C), zero(C)
|
||||
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C))
|
||||
|
||||
for k in 1:n
|
||||
M = abs2.(Z) .< abs2(r)
|
||||
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1
|
||||
M = abs.(Z) .< r
|
||||
S[M], T[M] = S[M] .+ cos.(stripes .* angle.(Z[M])), T[M] .+ 1
|
||||
Z[M], dZ[M], ddZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1, 2 .* (dZ[M] .^ 2 .+ Z[M] .* ddZ[M])
|
||||
end
|
||||
|
||||
N = abs.(Z) .> 2 # exterior distance estimation
|
||||
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N])
|
||||
N = abs.(Z) .>= r # normal map effect 1 (equipotential lines)
|
||||
P, Q = S[N] ./ T[N], (S[N] .+ cos.(stripes .* angle.(Z[N]))) ./ (T[N] .+ 1)
|
||||
R = Q .+ (P .- Q) .* log2.(log.(abs.(Z[N])) ./ log(r)) # linear interpolation
|
||||
U, V = Z[N] ./ dZ[N], 1 .+ R ./ damping # normal vectors and variations in inclination
|
||||
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit vectors
|
||||
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ V .* height) ./ (1 + height), 0)
|
||||
|
||||
heatmap(D' .^ 0.05, c=:nipy_spectral)
|
||||
savefig("Mercator_Mandelbrot_map.png")
|
||||
heatmap(D .^ 1.0, c=:bone_1)
|
||||
savefig("Mandelbrot_normal_map_1.png")
|
||||
|
||||
X, Y = real(C), imag(C) # zoom images (adjust circle size 50 and zoom level 20 as needed)
|
||||
R, c, z = 50 * (2 / d) * pi .* exp.(.- B), min(d, h) + 1, max(0, h - d) ÷ 20
|
||||
N = abs.(Z) .> 2 # normal map effect 2 (equidistant lines)
|
||||
U = Z[N] .* dZ[N] .* ((1 .+ log.(abs.(Z[N]))) .* conj.(dZ[N] .^ 2) .- log.(abs.(Z[N])) .* conj.(Z[N] .* ddZ[N]))
|
||||
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit vectors
|
||||
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0)
|
||||
|
||||
gr(c=:nipy_spectral, axis=true, ticks=true, legend=false, markerstrokewidth=0)
|
||||
p1 = scatter(X[1z+1:1z+c,1:d], Y[1z+1:1z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[1z+1:1z+c,1:d].^0.5)
|
||||
p2 = scatter(X[2z+1:2z+c,1:d], Y[2z+1:2z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[2z+1:2z+c,1:d].^0.4)
|
||||
p3 = scatter(X[3z+1:3z+c,1:d], Y[3z+1:3z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[3z+1:3z+c,1:d].^0.3)
|
||||
p4 = scatter(X[4z+1:4z+c,1:d], Y[4z+1:4z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[4z+1:4z+c,1:d].^0.2)
|
||||
plot(p1, p2, p3, p4, layout=(2, 2))
|
||||
savefig("Mercator_Mandelbrot_zoom.png")
|
||||
heatmap(D .^ 1.0, c=:afmhot)
|
||||
savefig("Mandelbrot_normal_map_2.png")
|
||||
|
|
|
|||
|
|
@ -1,46 +1,39 @@
|
|||
using Plots
|
||||
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
|
||||
|
||||
setprecision(BigFloat, 256) # set precision to 256 bits (default)
|
||||
setrounding(BigFloat, RoundNearest) # set rounding mode (default)
|
||||
d, h = 200, 1200 # pixel density (= image width) and image height
|
||||
n, r = 8000, 10000 # number of iterations and escape radius (r > 2)
|
||||
|
||||
d, h = 50, 1000 # pixel density (= image width) and image height
|
||||
n, r = 80000, 100000 # number of iterations and escape radius (r > 2)
|
||||
|
||||
a = BigFloat("-1.256827152259138864846434197797294538253477389787308085590211144291")
|
||||
b = BigFloat(".37933802890364143684096784819544060002129071484943239316486643285025")
|
||||
|
||||
S = zeros(Complex{Float64}, n+1)
|
||||
let c = a + b * im, z = zero(c)
|
||||
for k in 1:n+1
|
||||
S[k] = z
|
||||
if abs2(z) < abs2(r)
|
||||
z = z ^ 2 + c
|
||||
else
|
||||
println("The reference sequence diverges within $(k-1) iterations.")
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
a = -.743643887037158704752191506114774 # real coordinate of the zoom center
|
||||
b = 0.131825904205311970493132056385139 # imaginary coordinate of the center
|
||||
|
||||
x = range(0, 2, length=d+1)
|
||||
y = range(0, 2 * h / d, length=h+1)
|
||||
|
||||
A, B = collect(x) .* pi, collect(y) .* pi
|
||||
C = 8.0 .* exp.((A' .+ B .* im) .* im)
|
||||
C = 8.0 .* exp.((A' .+ B .* im) .* im) .+ (a + b * im)
|
||||
|
||||
E, Z, dZ = zero(C), zero(C), zero(C)
|
||||
D, I, J = zeros(size(C)), ones(Int64, size(C)), ones(Int64, size(C))
|
||||
Z, dZ = zero(C), zero(C)
|
||||
D = zeros(size(C))
|
||||
|
||||
for k in 1:n
|
||||
M, R = abs2.(Z) .< abs2(r), abs2.(Z) .< abs2.(E)
|
||||
E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero
|
||||
E[M], I[M] = (2 .* S[I[M]] .+ E[M]) .* E[M] .+ C[M], I[M] .+ 1
|
||||
Z[M], dZ[M] = S[I[M]] .+ E[M], 2 .* Z[M] .* dZ[M] .+ 1
|
||||
M = abs2.(Z) .< abs2(r)
|
||||
Z[M], dZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1
|
||||
end
|
||||
|
||||
N = abs.(Z) .> 2 # exterior distance estimation
|
||||
D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N])
|
||||
|
||||
heatmap(D' .^ 0.015, c=:nipy_spectral)
|
||||
savefig("Mercator_Mandelbrot_deep_map.png")
|
||||
heatmap(D' .^ 0.05, c=:nipy_spectral)
|
||||
savefig("Mercator_Mandelbrot_map.png")
|
||||
|
||||
X, Y = real(C), imag(C) # zoom images (adjust circle size 50 and zoom level 20 as needed)
|
||||
R, c, z = 50 * (2 / d) * pi .* exp.(.- B), min(d, h) + 1, max(0, h - d) ÷ 20
|
||||
|
||||
gr(c=:nipy_spectral, axis=true, ticks=true, legend=false, markerstrokewidth=0)
|
||||
p1 = scatter(X[1z+1:1z+c,1:d], Y[1z+1:1z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[1z+1:1z+c,1:d].^0.5)
|
||||
p2 = scatter(X[2z+1:2z+c,1:d], Y[2z+1:2z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[2z+1:2z+c,1:d].^0.4)
|
||||
p3 = scatter(X[3z+1:3z+c,1:d], Y[3z+1:3z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[3z+1:3z+c,1:d].^0.3)
|
||||
p4 = scatter(X[4z+1:4z+c,1:d], Y[4z+1:4z+c,1:d], markersize=R[1:c].^0.5, marker_z=D[4z+1:4z+c,1:d].^0.2)
|
||||
plot(p1, p2, p3, p4, layout=(2, 2))
|
||||
savefig("Mercator_Mandelbrot_zoom.png")
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue