Egyptian division

Normal version

Only works with positive real numbers, not negative or complex.

sub egyptian-divmod (Real $dividend is copy where * >= 0, Real $divisor where * > 0) {
    my $accumulator = 0;
    ([1, $divisor], { [.[0] + .[0], .[1] + .[1]] } โ€ฆ ^ *.[1] > $dividend)
      .reverse.map: { $dividend -= .[1], $accumulator += .[0] if $dividend >= .[1] }
    $accumulator, $dividend;
}
 
#TESTING
for 580,34, 578,34, 7532795332300578,235117 -> $n, $d {
    printf "%s divmod %s = %s remainder %s\n",
        $n, $d, |egyptian-divmod( $n, $d )
}

Output:

580 divmod 34 = 17 remainder 2
578 divmod 34 = 17 remainder 0
7532795332300578 divmod 235117 = 32038497141 remainder 81

More "Egyptian" version

As a preceding version was determined to be "let's just say ... not Egyptian" we submit an alternate which is hopefully more "Egyptian". Now only handles positive Integers up to 10 million, mostly due to limitations on Egyptian notation for numbers.

Note: if the below is just a mass of "unknown glyph" boxes, try installing Googles free Noto Sans Egyptian Hieroglyphs font.

This is intended to be humorous and should not be regarded as good (or even sane) programming practice. That being said, ๐“‚ฝ & ๐“‚ป really are the ancient Egyptian symbols for addition and subtraction, and the Egyptian number notation is as accurate as possible. Everything else owes more to whimsy than rigor.

my (\๐“„ค, \๐“„Š, \๐“Ž†, \๐“„ฐ) = (0, 1, 10, 10e7);
sub infix:<๐“‚ฝ> { $^๐“ƒ  + $^๐“ƒŸ }
sub infix:<๐“‚ป> { $^๐“ƒฒ - $^๐“†Š }
sub infix:<๐“ˆ> { $^๐“ƒ• < $^๐“ƒข }
sub ๐“ถ (Int \๐“†‰) {
    my \๐“ข = [ยซ'' ๐“บ ๐“ป ๐“ผ ๐“ฝ ๐“พ ๐“ฟ ๐“€ ๐“ ๐“‚ยป], [ยซ'' ๐“Ž† ๐“Ž ๐“Ž ๐“Ž‘ ๐“ŽŠ ๐“Ž‹ ๐“ŽŒ ๐“Ž ๐“ŽŽยป],
      [ยซ'' ๐“ข ๐“ฃ ๐“ค ๐“ฅ ๐“ฆ ๐“ง ๐“จ ๐“ฉ ๐“ชยป], [ยซ'' ๐“†ผ ๐“†ฝ ๐“†พ ๐“†ฟ ๐“‡€ ๐“‡ ๐“‡‚ ๐“‡ƒ ๐“‡„ยป],
      [ยซ'' ๐“‚ญ ๐“‚ฎ ๐“‚ฏ ๐“‚ฐ ๐“‚ฑ ๐“‚ฒ ๐“‚ณ ๐“‚ด ๐“‚ตยป], ['๐“†' Xx ^๐“Ž†], ['๐“จ' Xx ^๐“Ž†];
    ([~] ๐“†‰.polymod( ๐“Ž† xx * ).map( { ๐“ข[$++;$_] } ).reverse) || '๐“„ค'
}

sub infix:<๐“…“> (Int $๐“‚€ is copy where ๐“„ค ๐“‚ป ๐“„Š ๐“ˆ * ๐“ˆ ๐“„ฐ, Int \๐“Œณ where ๐“„ค ๐“ˆ * ๐“ˆ ๐“„ฐ) {
    my $๐“Žฆ = ๐“„ค;
    ([๐“„Š,๐“Œณ], { [.[๐“„ค] ๐“‚ฝ .[๐“„ค], .[๐“„Š] ๐“‚ฝ .[๐“„Š]] } โ€ฆ ^$๐“‚€ ๐“ˆ *.[๐“„Š])
      .reverse.map: { $๐“‚€ ๐“‚ป= .[๐“„Š], $๐“Žฆ ๐“‚ฝ= .[๐“„ค] if .[๐“„Š] ๐“ˆ ($๐“‚€ ๐“‚ฝ ๐“„Š) }
    $๐“Žฆ, $๐“‚€;
}

#TESTING
for 580,34, 578,34, 2300578,23517 -> \๐“ƒพ, \๐“†™ {
    printf "%s divmod %s = %s remainder %s =OR= %s ๐“…“ %s = %s remainder %s\n",
        ๐“ƒพ, ๐“†™, |(๐“ƒพ ๐“…“ ๐“†™), (๐“ƒพ, ๐“†™, |(๐“ƒพ ๐“…“ ๐“†™))ยป.&๐“ถ;
}

Output:

580 divmod 34 = 17 remainder 2 =OR= ๐“ฆ๐“Ž ๐“…“ ๐“Ž๐“ฝ = ๐“Ž†๐“€ remainder ๐“ป
578 divmod 34 = 17 remainder 0 =OR= ๐“ฆ๐“ŽŒ๐“ ๐“…“ ๐“Ž๐“ฝ = ๐“Ž†๐“€ remainder ๐“„ค
2300578 divmod 23517 = 97 remainder 19429 =OR= ๐“จ๐“จ๐“†๐“†๐“†๐“ฆ๐“ŽŒ๐“ ๐“…“ ๐“‚ฎ๐“†พ๐“ฆ๐“Ž†๐“€ = ๐“ŽŽ๐“€ remainder ๐“‚ญ๐“‡„๐“ฅ๐“Ž๐“‚

Last updated