Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Fraction_reduction
note: Puzzles

View file

@ -0,0 +1,69 @@
''There is a fine line between numerator and denominator.''       ''─── anonymous''
A method to &nbsp; "reduce" &nbsp; some reducible fractions is to &nbsp; ''cross out'' &nbsp; <u>a</u> digit from the
numerator and the denominator. &nbsp; An example is:
<big>16</big> <big>1<b><strike>6</strike></b></big>
──── and then (simply) cross─out the sixes: ────
<big>64</big> <big><b><strike>6</strike></b>4</big>
resulting in:
<big>1</big>
───
<big>4</big>
Naturally, &nbsp; this "method" of reduction must reduce to the proper value &nbsp; (shown as a fraction).
This "method" is also known as &nbsp; ''anomalous cancellation'' &nbsp; and also &nbsp; ''accidental cancellation''.
(Of course, &nbsp; this "method" shouldn't be taught to impressionable or gullible minds.) &nbsp; &nbsp; &nbsp; <big><big><big> 😇 </big></big></big>
;Task:
Find and show some fractions that can be reduced by the above "method".
:* &nbsp; show 2-digit fractions found &nbsp; (like the example shown above)
:* &nbsp; show 3-digit fractions
:* &nbsp; show 4-digit fractions
:* &nbsp; show 5-digit fractions &nbsp; (and higher) &nbsp; &nbsp; &nbsp; ''(optional)''
:* &nbsp; show each (above) n-digit fractions separately from other different n-sized fractions, don't mix different "sizes" together
:* &nbsp; for each "size" fraction, &nbsp; only show a dozen examples &nbsp; (the 1<sup>st</sup> twelve found)
:* &nbsp; (it's recognized that not every programming solution will have the same generation algorithm)
:* &nbsp; for each "size" fraction:
:::* &nbsp; show a count of how many reducible fractions were found. &nbsp; The example (above) is size '''2'''
:::* &nbsp; show a count of which digits were crossed out &nbsp; (one line for each different digit)
:* &nbsp; for each "size" fraction, &nbsp; show a count of how many were found. &nbsp; The example (above) is size '''2'''
:* &nbsp; show each n-digit example &nbsp; (to be shown on one line):
:::* &nbsp; show each n-digit fraction
:::* &nbsp; show each reduced n-digit fraction
:::* &nbsp; show what digit was crossed out for the numerator and the denominator
;Task requirements/restrictions:
:* &nbsp; only proper fractions and their reductions &nbsp; (the result) &nbsp; are to be used &nbsp; (no vulgar fractions)
:* &nbsp; only positive fractions are to be used &nbsp; (no negative signs anywhere)
:* &nbsp; only base ten integers are to be used for the numerator and denominator
:* &nbsp; no zeros &nbsp; (decimal digit) &nbsp; can be used within the numerator or the denominator
:* &nbsp; the numerator and denominator should be composed of the same number of digits
:* &nbsp; no digit can be repeated in the numerator
:* &nbsp; no digit can be repeated in the denominator
:* &nbsp; (naturally) &nbsp; there should be a shared decimal digit in the numerator &nbsp; ''and'' &nbsp; the denominator
:* &nbsp; fractions can be shown as &nbsp; 16/64 &nbsp; (for example)
Show all output here, on this page.
;Somewhat related task:
:* &nbsp; [https://rosettacode.org/wiki/Farey_sequence Farey sequence] &nbsp; &nbsp; &nbsp; (It concerns fractions.)
;References:
:* &nbsp; Wikipedia entry: &nbsp; [https://en.wikipedia.org/wiki/Fraction_(mathematics)#Proper_and_improper_fractions proper and improper fractions].
:* &nbsp; Wikipedia entry: &nbsp; [https://en.wikipedia.org/wiki/Anomalous_cancellation anomalous cancellation and/or accidental cancellation].
<br><br>

View file

@ -0,0 +1,83 @@
F indexOf(haystack, needle)
V idx = 0
L(straw) haystack
I straw == needle
R idx
E
idx++
R -1
F getDigits(=n, =le, &digits)
L n > 0
V r = n % 10
I r == 0 | indexOf(digits, r) >= 0
R 0B
le--
digits[le] = r
n = Int(n / 10)
R 1B
F removeDigit(digits, le, idx)
V pows = [1, 10, 100, 1000, 10000]
V sum = 0
V pow = pows[le - 2]
V i = 0
L i < le
I i == idx
i++
L.continue
sum = sum + digits[i] * pow
pow = Int(pow / 10)
i++
R sum
V lims = [ [ 12, 97 ], [ 123, 986 ], [ 1234, 9875 ], [ 12345, 98764 ] ]
V count = [0] * 5
V omitted = [[0] * 10] * 5
V i = 0
L i < lims.len
V n = lims[i][0]
L n < lims[i][1]
V nDigits = [0] * (i + 2)
V nOk = getDigits(n, i + 2, &nDigits)
I !nOk
n++
L.continue
V d = n + 1
L d <= lims[i][1] + 1
V dDigits = [0] * (i + 2)
V dOk = getDigits(d, i + 2, &dDigits)
I !dOk
d++
L.continue
V nix = 0
L nix < nDigits.len
V digit = nDigits[nix]
V dix = indexOf(dDigits, digit)
I dix >= 0
V rn = removeDigit(nDigits, i + 2, nix)
V rd = removeDigit(dDigits, i + 2, dix)
I (1.0 * n / d) == (1.0 * rn / rd)
count[i]++
omitted[i][digit]++
I count[i] <= 12
print(#./#. = #./#. by omitting #.'s.format(n, d, rn, rd, digit))
nix++
d++
n++
print()
i++
i = 2
L i <= 5
print(There are #. #.-digit fractions of which:.format(count[i - 2], i))
V j = 1
L j <= 9
I omitted[i - 2][j] == 0
j++
L.continue
print(#6 have #.'s omitted.format(omitted[i - 2][j], j))
j++
print()
i++

View file

@ -0,0 +1,120 @@
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
procedure Fraction_Reduction is
type Int_Array is array (Natural range <>) of Integer;
function indexOf(haystack : Int_Array; needle : Integer) return Integer is
idx : Integer := 0;
begin
for straw of haystack loop
if straw = needle then
return idx;
else
idx := idx + 1;
end if;
end loop;
return -1;
end IndexOf;
function getDigits(n, le : in Integer;
digit_array : in out Int_Array) return Boolean is
n_local : Integer := n;
le_local : Integer := le;
r : Integer;
begin
while n_local > 0 loop
r := n_local mod 10;
if r = 0 or indexOf(digit_array, r) >= 0 then
return False;
end if;
le_local := le_local - 1;
digit_array(le_local) := r;
n_local := n_local / 10;
end loop;
return True;
end getDigits;
function removeDigit(digit_array : Int_Array;
le, idx : Integer) return Integer is
sum : Integer := 0;
pow : Integer := 10 ** (le - 2);
begin
for i in 0 .. le - 1 loop
if i /= idx then
sum := sum + digit_array(i) * pow;
pow := pow / 10;
end if;
end loop;
return sum;
end removeDigit;
lims : constant array (0 .. 3) of Int_Array (0 .. 1) :=
((12, 97), (123, 986), (1234, 9875), (12345, 98764));
count : Int_Array (0 .. 4) := (others => 0);
omitted : array (0 .. 4) of Int_Array (0 .. 9) :=
(others => (others => 0));
begin
Ada.Integer_Text_IO.Default_Width := 0;
for i in lims'Range loop
declare
nDigits, dDigits : Int_Array (0 .. i + 1);
digit, dix, rn, rd : Integer;
begin
for n in lims(i)(0) .. lims(i)(1) loop
nDigits := (others => 0);
if getDigits(n, i + 2, nDigits) then
for d in n + 1 .. lims(i)(1) + 1 loop
dDigits := (others => 0);
if getDigits(d, i + 2, dDigits) then
for nix in nDigits'Range loop
digit := nDigits(nix);
dix := indexOf(dDigits, digit);
if dix >= 0 then
rn := removeDigit(nDigits, i + 2, nix);
rd := removeDigit(dDigits, i + 2, dix);
-- 'n/d = rn/rd' is same as 'n*rd = rn*d'
if n*rd = rn*d then
count(i) := count(i) + 1;
omitted(i)(digit) :=
omitted(i)(digit) + 1;
if count(i) <= 12 then
Put (n);
Put ("/");
Put (d);
Put (" = ");
Put (rn);
Put ("/");
Put (rd);
Put (" by omitting ");
Put (digit);
Put_Line ("'s");
end if;
end if;
end if;
end loop;
end if;
end loop;
end if;
end loop;
end;
New_Line;
end loop;
for i in 2 .. 5 loop
Put ("There are ");
Put (count(i - 2));
Put (" ");
Put (i);
Put_Line ("-digit fractions of which:");
for j in 1 .. 9 loop
if omitted(i - 2)(j) /= 0 then
Put (omitted(i - 2)(j), Width => 6);
Put (" have ");
Put (j);
Put_Line ("'s omitted");
end if;
end loop;
New_Line;
end loop;
end Fraction_Reduction;

View file

@ -0,0 +1,106 @@
#include <array>
#include <iomanip>
#include <iostream>
#include <vector>
int indexOf(const std::vector<int> &haystack, int needle) {
auto it = haystack.cbegin();
auto end = haystack.cend();
int idx = 0;
for (; it != end; it = std::next(it)) {
if (*it == needle) {
return idx;
}
idx++;
}
return -1;
}
bool getDigits(int n, int le, std::vector<int> &digits) {
while (n > 0) {
auto r = n % 10;
if (r == 0 || indexOf(digits, r) >= 0) {
return false;
}
le--;
digits[le] = r;
n /= 10;
}
return true;
}
int removeDigit(const std::vector<int> &digits, int le, int idx) {
static std::array<int, 5> pows = { 1, 10, 100, 1000, 10000 };
int sum = 0;
auto pow = pows[le - 2];
for (int i = 0; i < le; i++) {
if (i == idx) continue;
sum += digits[i] * pow;
pow /= 10;
}
return sum;
}
int main() {
std::vector<std::pair<int, int>> lims = { {12, 97}, {123, 986}, {1234, 9875}, {12345, 98764} };
std::array<int, 5> count;
std::array<std::array<int, 10>, 5> omitted;
std::fill(count.begin(), count.end(), 0);
std::for_each(omitted.begin(), omitted.end(),
[](auto &a) {
std::fill(a.begin(), a.end(), 0);
}
);
for (size_t i = 0; i < lims.size(); i++) {
std::vector<int> nDigits(i + 2);
std::vector<int> dDigits(i + 2);
for (int n = lims[i].first; n <= lims[i].second; n++) {
std::fill(nDigits.begin(), nDigits.end(), 0);
bool nOk = getDigits(n, i + 2, nDigits);
if (!nOk) {
continue;
}
for (int d = n + 1; d <= lims[i].second + 1; d++) {
std::fill(dDigits.begin(), dDigits.end(), 0);
bool dOk = getDigits(d, i + 2, dDigits);
if (!dOk) {
continue;
}
for (size_t nix = 0; nix < nDigits.size(); nix++) {
auto digit = nDigits[nix];
auto dix = indexOf(dDigits, digit);
if (dix >= 0) {
auto rn = removeDigit(nDigits, i + 2, nix);
auto rd = removeDigit(dDigits, i + 2, dix);
if ((double)n / d == (double)rn / rd) {
count[i]++;
omitted[i][digit]++;
if (count[i] <= 12) {
std::cout << n << '/' << d << " = " << rn << '/' << rd << " by omitting " << digit << "'s\n";
}
}
}
}
}
}
std::cout << '\n';
}
for (int i = 2; i <= 5; i++) {
std::cout << "There are " << count[i - 2] << ' ' << i << "-digit fractions of which:\n";
for (int j = 1; j <= 9; j++) {
if (omitted[i - 2][j] == 0) {
continue;
}
std::cout << std::setw(6) << omitted[i - 2][j] << " have " << j << "'s omitted\n";
}
std::cout << '\n';
}
return 0;
}

View file

@ -0,0 +1,94 @@
using System;
namespace FractionReduction {
class Program {
static int IndexOf(int n, int[] s) {
for (int i = 0; i < s.Length; i++) {
if (s[i] == n) {
return i;
}
}
return -1;
}
static bool GetDigits(int n, int le, int[] digits) {
while (n > 0) {
var r = n % 10;
if (r == 0 || IndexOf(r, digits) >= 0) {
return false;
}
le--;
digits[le] = r;
n /= 10;
}
return true;
}
static int RemoveDigit(int[] digits, int le, int idx) {
int[] pows = { 1, 10, 100, 1000, 10000 };
var sum = 0;
var pow = pows[le - 2];
for (int i = 0; i < le; i++) {
if (i == idx) continue;
sum += digits[i] * pow;
pow /= 10;
}
return sum;
}
static void Main() {
var lims = new int[,] { { 12, 97 }, { 123, 986 }, { 1234, 9875 }, { 12345, 98764 } };
var count = new int[5];
var omitted = new int[5, 10];
var upperBound = lims.GetLength(0);
for (int i = 0; i < upperBound; i++) {
var nDigits = new int[i + 2];
var dDigits = new int[i + 2];
var blank = new int[i + 2];
for (int n = lims[i, 0]; n <= lims[i, 1]; n++) {
blank.CopyTo(nDigits, 0);
var nOk = GetDigits(n, i + 2, nDigits);
if (!nOk) {
continue;
}
for (int d = n + 1; d <= lims[i, 1] + 1; d++) {
blank.CopyTo(dDigits, 0);
var dOk = GetDigits(d, i + 2, dDigits);
if (!dOk) {
continue;
}
for (int nix = 0; nix < nDigits.Length; nix++) {
var digit = nDigits[nix];
var dix = IndexOf(digit, dDigits);
if (dix >= 0) {
var rn = RemoveDigit(nDigits, i + 2, nix);
var rd = RemoveDigit(dDigits, i + 2, dix);
if ((double)n / d == (double)rn / rd) {
count[i]++;
omitted[i, digit]++;
if (count[i] <= 12) {
Console.WriteLine("{0}/{1} = {2}/{3} by omitting {4}'s", n, d, rn, rd, digit);
}
}
}
}
}
}
Console.WriteLine();
}
for (int i = 2; i <= 5; i++) {
Console.WriteLine("There are {0} {1}-digit fractions of which:", count[i - 2], i);
for (int j = 1; j <= 9; j++) {
if (omitted[i - 2, j] == 0) {
continue;
}
Console.WriteLine("{0,6} have {1}'s omitted", omitted[i - 2, j], j);
}
Console.WriteLine();
}
}
}
}

View file

@ -0,0 +1,137 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct IntArray_t {
int *ptr;
size_t length;
} IntArray;
IntArray make(size_t size) {
IntArray temp;
temp.ptr = calloc(size, sizeof(int));
temp.length = size;
return temp;
}
void destroy(IntArray *ia) {
if (ia->ptr != NULL) {
free(ia->ptr);
ia->ptr = NULL;
ia->length = 0;
}
}
void zeroFill(IntArray dst) {
memset(dst.ptr, 0, dst.length * sizeof(int));
}
int indexOf(const int n, const IntArray ia) {
size_t i;
for (i = 0; i < ia.length; i++) {
if (ia.ptr[i] == n) {
return i;
}
}
return -1;
}
bool getDigits(int n, int le, IntArray digits) {
while (n > 0) {
int r = n % 10;
if (r == 0 || indexOf(r, digits) >= 0) {
return false;
}
le--;
digits.ptr[le] = r;
n /= 10;
}
return true;
}
int removeDigit(IntArray digits, size_t le, size_t idx) {
static const int POWS[] = { 1, 10, 100, 1000, 10000 };
int sum = 0;
int pow = POWS[le - 2];
size_t i;
for (i = 0; i < le; i++) {
if (i == idx) continue;
sum += digits.ptr[i] * pow;
pow /= 10;
}
return sum;
}
int main() {
int lims[4][2] = { { 12, 97 }, { 123, 986 }, { 1234, 9875 }, { 12345, 98764 } };
int count[5] = { 0 };
int omitted[5][10] = { {0} };
size_t upperBound = sizeof(lims) / sizeof(lims[0]);
size_t i;
for (i = 0; i < upperBound; i++) {
IntArray nDigits = make(i + 2);
IntArray dDigits = make(i + 2);
int n;
for (n = lims[i][0]; n <= lims[i][1]; n++) {
int d;
bool nOk;
zeroFill(nDigits);
nOk = getDigits(n, i + 2, nDigits);
if (!nOk) {
continue;
}
for (d = n + 1; d <= lims[i][1] + 1; d++) {
size_t nix;
bool dOk;
zeroFill(dDigits);
dOk = getDigits(d, i + 2, dDigits);
if (!dOk) {
continue;
}
for (nix = 0; nix < nDigits.length; nix++) {
int digit = nDigits.ptr[nix];
int dix = indexOf(digit, dDigits);
if (dix >= 0) {
int rn = removeDigit(nDigits, i + 2, nix);
int rd = removeDigit(dDigits, i + 2, dix);
if ((double)n / d == (double)rn / rd) {
count[i]++;
omitted[i][digit]++;
if (count[i] <= 12) {
printf("%d/%d = %d/%d by omitting %d's\n", n, d, rn, rd, digit);
}
}
}
}
}
}
printf("\n");
destroy(&nDigits);
destroy(&dDigits);
}
for (i = 2; i <= 5; i++) {
int j;
printf("There are %d %d-digit fractions of which:\n", count[i - 2], i);
for (j = 1; j <= 9; j++) {
if (omitted[i - 2][j] == 0) {
continue;
}
printf("%6d have %d's omitted\n", omitted[i - 2][j], j);
}
printf("\n");
}
return 0;
}

View file

@ -0,0 +1,91 @@
import std.range;
import std.stdio;
int indexOf(Range, Element)(Range haystack, scope Element needle)
if (isInputRange!Range) {
int idx;
foreach (straw; haystack) {
if (straw == needle) {
return idx;
}
idx++;
}
return -1;
}
bool getDigits(int n, int le, int[] digits) {
while (n > 0) {
auto r = n % 10;
if (r == 0 || indexOf(digits, r) >= 0) {
return false;
}
le--;
digits[le] = r;
n /= 10;
}
return true;
}
int removeDigit(int[] digits, int le, int idx) {
enum pows = [ 1, 10, 100, 1_000, 10_000 ];
int sum = 0;
auto pow = pows[le - 2];
for (int i = 0; i < le; i++) {
if (i == idx) continue;
sum += digits[i] * pow;
pow /= 10;
}
return sum;
}
void main() {
auto lims = [ [ 12, 97 ], [ 123, 986 ], [ 1234, 9875 ], [ 12345, 98764 ] ];
int[5] count;
int[10][5] omitted;
for (int i = 0; i < lims.length; i++) {
auto nDigits = new int[i + 2];
auto dDigits = new int[i + 2];
for (int n = lims[i][0]; n <= lims[i][1]; n++) {
nDigits[] = 0;
bool nOk = getDigits(n, i + 2, nDigits);
if (!nOk) {
continue;
}
for (int d = n + 1; d <= lims[i][1] + 1; d++) {
dDigits[] = 0;
bool dOk = getDigits(d, i + 2, dDigits);
if (!dOk) {
continue;
}
for (int nix = 0; nix < nDigits.length; nix++) {
auto digit = nDigits[nix];
auto dix = indexOf(dDigits, digit);
if (dix >= 0) {
auto rn = removeDigit(nDigits, i + 2, nix);
auto rd = removeDigit(dDigits, i + 2, dix);
if (cast(double)n / d == cast(double)rn / rd) {
count[i]++;
omitted[i][digit]++;
if (count[i] <= 12) {
writefln("%d/%d = %d/%d by omitting %d's", n, d, rn, rd, digit);
}
}
}
}
}
}
writeln;
}
for (int i = 2; i <= 5; i++) {
writefln("There are %d %d-digit fractions of which:", count[i - 2], i);
for (int j = 1; j <= 9; j++) {
if (omitted[i - 2][j] == 0) {
continue;
}
writefln("%6s have %d's omitted", omitted[i - 2][j], j);
}
writeln;
}
}

View file

@ -0,0 +1,101 @@
package main
import (
"fmt"
"time"
)
func indexOf(n int, s []int) int {
for i, j := range s {
if n == j {
return i
}
}
return -1
}
func getDigits(n, le int, digits []int) bool {
for n > 0 {
r := n % 10
if r == 0 || indexOf(r, digits) >= 0 {
return false
}
le--
digits[le] = r
n /= 10
}
return true
}
var pows = [5]int{1, 10, 100, 1000, 10000}
func removeDigit(digits []int, le, idx int) int {
sum := 0
pow := pows[le-2]
for i := 0; i < le; i++ {
if i == idx {
continue
}
sum += digits[i] * pow
pow /= 10
}
return sum
}
func main() {
start := time.Now()
lims := [5][2]int{
{12, 97},
{123, 986},
{1234, 9875},
{12345, 98764},
{123456, 987653},
}
var count [5]int
var omitted [5][10]int
for i, lim := range lims {
nDigits := make([]int, i+2)
dDigits := make([]int, i+2)
blank := make([]int, i+2)
for n := lim[0]; n <= lim[1]; n++ {
copy(nDigits, blank)
nOk := getDigits(n, i+2, nDigits)
if !nOk {
continue
}
for d := n + 1; d <= lim[1]+1; d++ {
copy(dDigits, blank)
dOk := getDigits(d, i+2, dDigits)
if !dOk {
continue
}
for nix, digit := range nDigits {
if dix := indexOf(digit, dDigits); dix >= 0 {
rn := removeDigit(nDigits, i+2, nix)
rd := removeDigit(dDigits, i+2, dix)
if float64(n)/float64(d) == float64(rn)/float64(rd) {
count[i]++
omitted[i][digit]++
if count[i] <= 12 {
fmt.Printf("%d/%d = %d/%d by omitting %d's\n", n, d, rn, rd, digit)
}
}
}
}
}
}
fmt.Println()
}
for i := 2; i <= 6; i++ {
fmt.Printf("There are %d %d-digit fractions of which:\n", count[i-2], i)
for j := 1; j <= 9; j++ {
if omitted[i-2][j] == 0 {
continue
}
fmt.Printf("%6d have %d's omitted\n", omitted[i-2][j], j)
}
fmt.Println()
}
fmt.Printf("Took %s\n", time.Since(start))
}

View file

@ -0,0 +1,120 @@
package main
import (
"fmt"
"time"
)
type result struct {
n int
nine [9]int
}
func indexOf(n int, s []int) int {
for i, j := range s {
if n == j {
return i
}
}
return -1
}
func bIndexOf(b bool, s []bool) int {
for i, j := range s {
if b == j {
return i
}
}
return -1
}
func toNumber(digits []int, removeDigit int) int {
digits2 := digits
if removeDigit != 0 {
digits2 = make([]int, len(digits))
copy(digits2, digits)
d := indexOf(removeDigit, digits2)
copy(digits2[d:], digits2[d+1:])
digits2[len(digits2)-1] = 0
digits2 = digits2[:len(digits2)-1]
}
res := digits2[0]
for i := 1; i < len(digits2); i++ {
res = res*10 + digits2[i]
}
return res
}
func nDigits(n int) []result {
var res []result
digits := make([]int, n)
var used [9]bool
for i := 0; i < n; i++ {
digits[i] = i + 1
used[i] = true
}
for {
var nine [9]int
for i := 0; i < len(used); i++ {
if used[i] {
nine[i] = toNumber(digits, i+1)
}
}
res = append(res, result{toNumber(digits, 0), nine})
found := false
for i := n - 1; i >= 0; i-- {
d := digits[i]
if !used[d-1] {
panic("something went wrong with 'used' array")
}
used[d-1] = false
for j := d; j < 9; j++ {
if !used[j] {
used[j] = true
digits[i] = j + 1
for k := i + 1; k < n; k++ {
digits[k] = bIndexOf(false, used[:]) + 1
used[digits[k]-1] = true
}
found = true
break
}
}
if found {
break
}
}
if !found {
break
}
}
return res
}
func main() {
start := time.Now()
for n := 2; n <= 5; n++ {
rs := nDigits(n)
count := 0
var omitted [9]int
for i := 0; i < len(rs)-1; i++ {
xn, rn := rs[i].n, rs[i].nine
for j := i + 1; j < len(rs); j++ {
xd, rd := rs[j].n, rs[j].nine
for k := 0; k < 9; k++ {
yn, yd := rn[k], rd[k]
if yn != 0 && yd != 0 &&
float64(xn)/float64(xd) == float64(yn)/float64(yd) {
count++
omitted[k]++
if count <= 12 {
fmt.Printf("%d/%d => %d/%d (removed %d)\n", xn, xd, yn, yd, k+1)
}
}
}
}
}
fmt.Printf("%d-digit fractions found:%d, omitted %v\n\n", n, count, omitted)
}
fmt.Printf("Took %s\n", time.Since(start))
}

View file

@ -0,0 +1,100 @@
class FractionReduction {
static void main(String[] args) {
for (int size = 2; size <= 5; size++) {
reduce(size)
}
}
private static void reduce(int numDigits) {
System.out.printf("Fractions with digits of length %d where cancellation is valid. Examples:%n", numDigits)
// Generate allowed numerator's and denominator's
int min = (int) Math.pow(10, numDigits - 1)
int max = (int) Math.pow(10, numDigits) - 1
List<Integer> values = new ArrayList<>()
for (int number = min; number <= max; number++) {
if (isValid(number)) {
values.add(number)
}
}
Map<Integer, Integer> cancelCount = new HashMap<>()
int size = values.size()
int solutions = 0
for (int nIndex = 0; nIndex < size - 1; nIndex++) {
int numerator = values.get(nIndex)
// Must be proper fraction
for (int dIndex = nIndex + 1; dIndex < size; dIndex++) {
int denominator = values.get(dIndex)
for (int commonDigit : digitsInCommon(numerator, denominator)) {
int numRemoved = removeDigit(numerator, commonDigit)
int denRemoved = removeDigit(denominator, commonDigit)
if (numerator * denRemoved == denominator * numRemoved) {
solutions++
cancelCount.merge(commonDigit, 1, { v1, v2 -> v1 + v2 })
if (solutions <= 12) {
println(" When $commonDigit is removed, $numerator/$denominator = $numRemoved/$denRemoved")
}
}
}
}
}
println("Number of fractions where cancellation is valid = $solutions.")
List<Integer> sorted = new ArrayList<>(cancelCount.keySet())
Collections.sort(sorted)
for (int removed : sorted) {
println(" The digit $removed was removed ${cancelCount.get(removed)} times.")
}
println()
}
private static int[] powers = [1, 10, 100, 1000, 10000, 100000]
// Remove the specified digit.
private static int removeDigit(int n, int removed) {
int m = 0
int pow = 0
while (n > 0) {
int r = n % 10
if (r != removed) {
m = m + r * powers[pow]
pow++
}
n /= 10
}
return m
}
// Assumes no duplicate digits individually in n1 or n2 - part of task
private static List<Integer> digitsInCommon(int n1, int n2) {
int[] count = new int[10]
List<Integer> common = new ArrayList<>()
while (n1 > 0) {
int r = n1 % 10
count[r] += 1
n1 /= 10
}
while (n2 > 0) {
int r = n2 % 10
if (count[r] > 0) {
common.add(r)
}
n2 /= 10
}
return common
}
// No repeating digits, no digit is zero.
private static boolean isValid(int num) {
int[] count = new int[10]
while (num > 0) {
int r = num % 10
if (r == 0 || count[r] == 1) {
return false
}
count[r] = 1
num /= 10
}
return true
}
}

View file

@ -0,0 +1,55 @@
import Control.Monad (guard)
import Data.List (intersect, unfoldr, delete, nub, group, sort)
import Text.Printf (printf)
type Fraction = (Int, Int)
type Reduction = (Fraction, Fraction, Int)
validIntegers :: [Int] -> [Int]
validIntegers xs = [x | x <- xs, not $ hasZeros x, hasUniqueDigits x]
where
hasZeros = elem 0 . digits 10
hasUniqueDigits n = length ds == length ul
where
ds = digits 10 n
ul = nub ds
possibleFractions :: [Int] -> [Fraction]
possibleFractions = (\ys -> [(n,d) | n <- ys, d <- ys, n < d, gcd n d /= 1]) . validIntegers
digits :: Integral a => a -> a -> [a]
digits b = unfoldr (\n -> guard (n /= 0) >> pure (n `mod` b, n `div` b))
digitsToIntegral :: Integral a => [a] -> a
digitsToIntegral = sum . zipWith (*) (iterate (*10) 1)
findReductions :: Fraction -> [Reduction]
findReductions z@(n1, d1) = [ (z, (n2, d2), x)
| x <- digits 10 n1 `intersect` digits 10 d1,
let n2 = dropDigit x n1
d2 = dropDigit x d1
decimalWithDrop = realToFrac n2 / realToFrac d2,
decimalWithDrop == decimal ]
where dropDigit d = digitsToIntegral . delete d . digits 10
decimal = realToFrac n1 / realToFrac d1
findGroupReductions :: [Int] -> [Reduction]
findGroupReductions = (findReductions =<<) . possibleFractions
showReduction :: Reduction -> IO ()
showReduction ((n1,d1),(n2,d2),d) = printf "%d/%d = %d/%d by dropping %d\n" n1 d1 n2 d2 d
showCount :: [Reduction] -> Int -> IO ()
showCount xs n = do
printf "There are %d %d-digit fractions of which:\n" (length xs) n
mapM_ (uncurry (printf "%5d have %d's omitted\n")) (countReductions xs) >> printf "\n"
where
countReductions = fmap ((,) . length <*> head) . group . sort . fmap (\(_, _, x) -> x)
main :: IO ()
main = do
mapM_ (\g -> mapM_ showReduction (take 12 g) >> printf "\n") groups
mapM_ (uncurry showCount) $ zip groups [2..]
where
groups = [ findGroupReductions [10^1..99], findGroupReductions [10^2..999]
, findGroupReductions [10^3..9999], findGroupReductions [10^4..99999] ]

View file

@ -0,0 +1,54 @@
Filter=: (#~`)(`:6)
assert 'ac' -: 1 0 1"_ Filter 'abc'
intersect=:-.^:2
assert 'ab' -: 'abc'intersect'razb'
odometer=: (4$.$.)@:($&1)
Note 'odometer 2 3'
0 0
0 1
0 2
1 0
1 1
1 2
)
common=: 0 e. ~:
assert common 1 2 1
assert -. common 1 2 3
o=: '123456789' {~ [: -.@:common"1 Filter odometer@:(#&9) NB. o is y unique digits, all of them
f=: ,:"1/&g~ NB. f computes a table of all numerators and denominators pairs
mask=: [: </~&i. # NB. the lower triangle will become proper fractions
av=: (([: , mask) # ,/)@:f NB. anti-vulgarization
c=: [: common@:,/"2 Filter av NB. ensure common digit(s)
fac=: [: ([: common ,&:~.&:q:&:"./)"2 Filter c NB. assure a common factor
NB. This common factor filter might be useful in a future fully tacit version of the program.
cancellation=: monad define
NDL =. c y NB. vector of literal numerator and denominator
NB. retain reducible fractions
ND =. ". NDL NB. integral version of NDL
MASK=. ([: common ,&:~.&:q:/)"1 ND NB. assure a common factor
FRAC=. _2 x: MASK # ND NB. division
CANDIDATES=. MASK # NDL
rat=. , 'r'&,
result=. 0 3 $ a:
for_i. i. # CANDIDATES do.
fraction =. i { FRAC
pair=. i { CANDIDATES
for_d. intersect/ pair do.
trial=. pair -."1 d
if. fraction = _2 x: ". trial do.
result =. result , (rat/pair) ; (rat/trial) ; d
end.
end.
end.
result
)

View file

@ -0,0 +1,108 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FractionReduction {
public static void main(String[] args) {
for ( int size = 2 ; size <= 5 ; size++ ) {
reduce(size);
}
}
private static void reduce(int numDigits) {
System.out.printf("Fractions with digits of length %d where cancellation is valid. Examples:%n", numDigits);
// Generate allowed numerator's and denominator's
int min = (int) Math.pow(10, numDigits-1);
int max = (int) Math.pow(10, numDigits) - 1;
List<Integer> values = new ArrayList<>();
for ( int number = min ; number <= max ; number++ ) {
if ( isValid(number) ) {
values.add(number);
}
}
Map<Integer,Integer> cancelCount = new HashMap<>();
int size = values.size();
int solutions = 0;
for ( int nIndex = 0 ; nIndex < size - 1 ; nIndex++ ) {
int numerator = values.get(nIndex);
// Must be proper fraction
for ( int dIndex = nIndex + 1 ; dIndex < size ; dIndex++ ) {
int denominator = values.get(dIndex);
for ( int commonDigit : digitsInCommon(numerator, denominator) ) {
int numRemoved = removeDigit(numerator, commonDigit);
int denRemoved = removeDigit(denominator, commonDigit);
if ( numerator * denRemoved == denominator * numRemoved ) {
solutions++;
cancelCount.merge(commonDigit, 1, (v1, v2) -> v1 + v2);
if ( solutions <= 12 ) {
System.out.printf(" When %d is removed, %d/%d = %d/%d%n", commonDigit, numerator, denominator, numRemoved, denRemoved);
}
}
}
}
}
System.out.printf("Number of fractions where cancellation is valid = %d.%n", solutions);
List<Integer> sorted = new ArrayList<>(cancelCount.keySet());
Collections.sort(sorted);
for ( int removed : sorted ) {
System.out.printf(" The digit %d was removed %d times.%n", removed, cancelCount.get(removed));
}
System.out.println();
}
private static int[] powers = new int[] {1, 10, 100, 1000, 10000, 100000};
// Remove the specified digit.
private static int removeDigit(int n, int removed) {
int m = 0;
int pow = 0;
while ( n > 0 ) {
int r = n % 10;
if ( r != removed ) {
m = m + r*powers[pow];
pow++;
}
n /= 10;
}
return m;
}
// Assumes no duplicate digits individually in n1 or n2 - part of task
private static List<Integer> digitsInCommon(int n1, int n2) {
int[] count = new int[10];
List<Integer> common = new ArrayList<>();
while ( n1 > 0 ) {
int r = n1 % 10;
count[r] += 1;
n1 /= 10;
}
while ( n2 > 0 ) {
int r = n2 % 10;
if ( count[r] > 0 ) {
common.add(r);
}
n2 /= 10;
}
return common;
}
// No repeating digits, no digit is zero.
private static boolean isValid(int num) {
int[] count = new int[10];
while ( num > 0 ) {
int r = num % 10;
if ( r == 0 || count[r] == 1 ) {
return false;
}
count[r] = 1;
num /= 10;
}
return true;
}
}

View file

@ -0,0 +1,43 @@
using Combinatorics
toi(set) = parse(Int, join(set, ""))
drop1(c, set) = toi(filter(x -> x != c, set))
function anomalouscancellingfractions(numdigits)
ret = Vector{Tuple{Int, Int, Int, Int, Int}}()
for nset in permutations(1:9, numdigits), dset in permutations(1:9, numdigits)
if nset < dset # only proper fractions
for c in nset
if c in dset # a common digit exists
n, d, nn, dd = toi(nset), toi(dset), drop1(c, nset), drop1(c, dset)
if n // d == nn // dd # anomalous cancellation
push!(ret, (n, d, nn, dd, c))
end
end
end
end
end
ret
end
function testfractionreduction(maxdigits=5)
for i in 2:maxdigits
results = anomalouscancellingfractions(i)
println("\nFor $i digits, there were ", length(results),
" fractions with anomalous cancellation.")
numcounts = zeros(Int, 9)
for r in results
numcounts[r[5]] += 1
end
for (j, count) in enumerate(numcounts)
count > 0 && println("The digit $j was crossed out $count times.")
end
println("Examples:")
for j in 1:min(length(results), 12)
r = results[j]
println(r[1], "/", r[2], " = ", r[3], "/", r[4], " ($(r[5]) crossed out)")
end
end
end
testfractionreduction()

View file

@ -0,0 +1,104 @@
fun indexOf(n: Int, s: IntArray): Int {
for (i_j in s.withIndex()) {
if (n == i_j.value) {
return i_j.index
}
}
return -1
}
fun getDigits(n: Int, le: Int, digits: IntArray): Boolean {
var mn = n
var mle = le
while (mn > 0) {
val r = mn % 10
if (r == 0 || indexOf(r, digits) >= 0) {
return false
}
mle--
digits[mle] = r
mn /= 10
}
return true
}
val pows = intArrayOf(1, 10, 100, 1_000, 10_000)
fun removeDigit(digits: IntArray, le: Int, idx: Int): Int {
var sum = 0
var pow = pows[le - 2]
for (i in 0 until le) {
if (i == idx) {
continue
}
sum += digits[i] * pow
pow /= 10
}
return sum
}
fun main() {
val lims = listOf(
Pair(12, 97),
Pair(123, 986),
Pair(1234, 9875),
Pair(12345, 98764)
)
val count = IntArray(5)
var omitted = arrayOf<Array<Int>>()
for (i in 0 until 5) {
var array = arrayOf<Int>()
for (j in 0 until 10) {
array += 0
}
omitted += array
}
for (i_lim in lims.withIndex()) {
val i = i_lim.index
val lim = i_lim.value
val nDigits = IntArray(i + 2)
val dDigits = IntArray(i + 2)
val blank = IntArray(i + 2) { 0 }
for (n in lim.first..lim.second) {
blank.copyInto(nDigits)
val nOk = getDigits(n, i + 2, nDigits)
if (!nOk) {
continue
}
for (d in n + 1..lim.second + 1) {
blank.copyInto(dDigits)
val dOk = getDigits(d, i + 2, dDigits)
if (!dOk) {
continue
}
for (nix_digit in nDigits.withIndex()) {
val dix = indexOf(nix_digit.value, dDigits)
if (dix >= 0) {
val rn = removeDigit(nDigits, i + 2, nix_digit.index)
val rd = removeDigit(dDigits, i + 2, dix)
if (n.toDouble() / d.toDouble() == rn.toDouble() / rd.toDouble()) {
count[i]++
omitted[i][nix_digit.value]++
if (count[i] <= 12) {
println("$n/$d = $rn/$rd by omitting ${nix_digit.value}'s")
}
}
}
}
}
}
println()
}
for (i in 2..5) {
println("There are ${count[i - 2]} $i-digit fractions of which:")
for (j in 1..9) {
if (omitted[i - 2][j] == 0) {
continue
}
println("%6d have %d's omitted".format(omitted[i - 2][j], j))
}
println()
}
}

View file

@ -0,0 +1,103 @@
function indexOf(haystack, needle)
for idx,straw in pairs(haystack) do
if straw == needle then
return idx
end
end
return -1
end
function getDigits(n, le, digits)
while n > 0 do
local r = n % 10
if r == 0 or indexOf(digits, r) > 0 then
return false
end
le = le - 1
digits[le + 1] = r
n = math.floor(n / 10)
end
return true
end
function removeDigit(digits, le, idx)
local pows = { 1, 10, 100, 1000, 10000 }
local sum = 0
local pow = pows[le - 2 + 1]
for i = 1, le do
if i ~= idx then
sum = sum + digits[i] * pow
pow = math.floor(pow / 10)
end
end
return sum
end
function main()
local lims = { {12, 97}, {123, 986}, {1234, 9875}, {12345, 98764} }
local count = { 0, 0, 0, 0, 0 }
local omitted = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
}
for i,_ in pairs(lims) do
local nDigits = {}
local dDigits = {}
for j = 1, i + 2 - 1 do
nDigits[j] = -1
dDigits[j] = -1
end
for n = lims[i][1], lims[i][2] do
for j,_ in pairs(nDigits) do
nDigits[j] = 0
end
local nOk = getDigits(n, i + 2 - 1, nDigits)
if nOk then
for d = n + 1, lims[i][2] + 1 do
for j,_ in pairs(dDigits) do
dDigits[j] = 0
end
local dOk = getDigits(d, i + 2 - 1, dDigits)
if dOk then
for nix,_ in pairs(nDigits) do
local digit = nDigits[nix]
local dix = indexOf(dDigits, digit)
if dix >= 0 then
local rn = removeDigit(nDigits, i + 2 - 1, nix)
local rd = removeDigit(dDigits, i + 2 - 1, dix)
if (n / d) == (rn / rd) then
count[i] = count[i] + 1
omitted[i][digit + 1] = omitted[i][digit + 1] + 1
if count[i] <= 12 then
print(string.format("%d/%d = %d/%d by omitting %d's", n, d, rn, rd, digit))
end
end
end
end
end
end
end
end
print()
end
for i = 2, 5 do
print("There are "..count[i - 2 + 1].." "..i.."-digit fractions of which:")
for j = 1, 9 do
if omitted[i - 2 + 1][j + 1] > 0 then
print(string.format("%6d have %d's omitted", omitted[i - 2 + 1][j + 1], j))
end
end
print()
end
end
main()

View file

@ -0,0 +1,63 @@
ClearAll[AnomalousCancellationQ2]
AnomalousCancellationQ2[frac : {i_?Positive, j_?Positive}] :=
Module[{samedigits, idig, jdig, ff, p, q, r, tmp},
idig = IntegerDigits[i];
jdig = IntegerDigits[j];
samedigits = Intersection[idig, jdig];
ff = i/j;
If[samedigits != {},
r = {};
Do[
p = Flatten[Position[idig, s]];
q = Flatten[Position[jdig, s]];
p = FromDigits[Delete[idig, #]] & /@ p;
q = FromDigits[Delete[jdig, #]] & /@ q;
tmp = Select[Tuples[{p, q}], #[[1]]/#[[2]] == ff &];
If[Length[tmp] > 0,
r = Join[r, Join[#, {i, j, s}] & /@ tmp];
];
,
{s, samedigits}
];
r
,
{}
]
]
ijs = Select[Select[Range[1, 9999], IntegerDigits /* FreeQ[0]], IntegerDigits /* DuplicateFreeQ];
res = Reap[
Do[
Do[
num = ijs[[i]];
den = ijs[[j]];
out = AnomalousCancellationQ2[{num, den}];
If[Length[out] > 0,
Sow[out]
]
,
{i, 1, j - 1}
]
,
{j, Length[ijs]}
]
][[2, 1]];
tmp = Catenate[res];
sel = Sort@Select[tmp, IntegerLength[#[[3]]] == IntegerLength[#[[4]]] == 2 &];
Length[sel]
t = Take[sel, UpTo[12]];
Column[Row[{#3, "/", #4, " = ", #1, "/", #2, " by removing ", #5}] & @@@ t]
SortBy[Tally[sel[[All, -1]]], First]
sel = Sort@Select[tmp, IntegerLength[#[[3]]] == IntegerLength[#[[4]]] == 3 &];
Length[sel]
t = Take[sel, UpTo[12]];
Column[Row[{#3, "/", #4, " = ", #1, "/", #2, " by removing ", #5}] & @@@ t]
SortBy[Tally[sel[[All, -1]]], First]
sel = Sort@Select[tmp, IntegerLength[#[[3]]] == IntegerLength[#[[4]]] == 4 &];
Length[sel]
t = Take[sel, UpTo[12]];
Column[Row[{#3, "/", #4, " = ", #1, "/", #2, " by removing ", #5}] & @@@ t]
SortBy[Tally[sel[[All, -1]]], First]

View file

@ -0,0 +1,15 @@
%Fraction Reduction. Nigel Galloway, September 5th., 2019
include "alldifferent.mzn"; include "member.mzn";
int: S;
array [1..9] of int: Pn=[1,10,100,1000,10000,100000,1000000,10000000,100000000];
array [1..S] of var 1..9: Nz; constraint alldifferent(Nz);
array [1..S] of var 1..9: Gz; constraint alldifferent(Gz);
var int: n; constraint n=sum(n in 1..S)(Nz[n]*Pn[n]);
var int: i; constraint i=sum(n in 1..S)(Gz[n]*Pn[n]); constraint n<i; constraint n*g=i*e;
var int: g; constraint g=sum(n in 1..S)(if n=a then 0 elseif n>a then Gz[n]*Pn[n-1] else Gz[n]*Pn[n] endif);
var int: e; constraint e=sum(n in 1..S)(if n=l then 0 elseif n>l then Nz[n]*Pn[n-1] else Nz[n]*Pn[n] endif);
var 1..S: l; constraint Nz[l]=w;
var 1..S: a; constraint Gz[a]=w;
var 1..9: w; constraint member(Nz,w) /\ member(Gz,w);
output [show(n)++"/"++show(i)++" becomes "++show(e)++"/"++show(g)++" when "++show(w)++" is omitted"]

View file

@ -0,0 +1,73 @@
# Fraction reduction.
import strformat
import times
type Result = tuple[n: int, nine: array[1..9, int]]
template find[T; N: static int](a: array[1..N, T]; value: T): int =
## Return the one-based index of a value in an array.
## This is needed as "system.find" returns a 0-based index even if the
## array lower bound is not null.
system.find(a, value) + 1
func toNumber(digits: seq[int]; removeDigit: int = 0): int =
## Convert a list of digits into a number.
var digits = digits
if removeDigit != 0:
let idx = digits.find(removeDigit)
digits.delete(idx)
for d in digits:
result = 10 * result + d
func nDigits(n: int): seq[Result] =
var digits = newSeq[int](n + 1) # Allocating one more to work with one-based indexes.
var used: array[1..9, bool]
for i in 1..n:
digits[i] = i
used[i] = true
var terminated = false
while not terminated:
var nine: array[1..9, int]
for i in 1..9:
if used[i]:
nine[i] = digits.toNumber(i)
result &= (n: digits.toNumber(), nine: nine)
block searchLoop:
terminated = true
for i in countdown(n, 1):
let d = digits[i]
doAssert(used[d], "Encountered an inconsistency with 'used' array")
used[d] = false
for j in (d + 1)..9:
if not used[j]:
used[j] = true
digits[i] = j
for k in (i + 1)..n:
digits[k] = used.find(false)
used[digits[k]] = true
terminated = false
break searchLoop
let start = gettime()
for n in 2..6:
let rs = nDigits(n)
var count = 0
var omitted: array[1..9, int]
for i in 1..<rs.high:
let (xn, rn) = rs[i]
for j in (i + 1)..rs.high:
let (xd, rd) = rs[j]
for k in 1..9:
let yn = rn[k]
let yd = rd[k]
if yn != 0 and yd != 0 and xn * yd == yn * xd:
inc count
inc omitted[k]
if count <= 12:
echo &"{xn}/{xd} => {yn}/{yd} (removed {k})"
echo &"{n}-digit fractions found: {count}, omitted {omitted}\n"
echo &"Took {gettime() - start}"

View file

@ -0,0 +1,246 @@
program FracRedu;
{$IFDEF FPC}
{$MODE DELPHI}
{$OPTIMIZATION ON,ALL}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
SysUtils;
type
tdigit = 0..9;
const
cMaskDgt: array [tdigit] of Uint32 = (1, 2, 4, 8, 16, 32, 64, 128, 256, 512
{,1024,2048,4096,8193,16384,32768});
cMaxDigits = High(tdigit);
type
tPermfield = array[tdigit] of uint32;
tpPermfield = ^tPermfield;
tDigitCnt = array[tdigit] of Uint32;
tErg = record
numUsedDigits : Uint32;
numUnusedDigit : array[tdigit] of Uint32;
numNormal : Uint64;// so sqr of number stays in Uint64
dummy : array[0..7] of byte;//-> sizeof(tErg) = 64
end;
tpErg = ^tErg;
var
Erg: array of tErg;
pf_x, pf_y: tPermfield;
DigitCnt :tDigitCnt;
permcnt, UsedDigits,Anzahl: NativeUint;
function Fakultaet(i: integer): integer;
begin
Result := 1;
while i > 1 do
begin
Result := Result * i;
Dec(i);
end;
end;
procedure OutErg(dgt: Uint32;pi,pJ:tpErg);
begin
writeln(dgt:3,' ', pi^.numUnusedDigit[dgt],'/',pj^.numUnusedDigit[dgt]
,' = ',pi^.numNormal,'/',pj^.numNormal);
end;
function Check(pI,pJ : tpErg;Nud :Word):integer;
var
dgt: NativeInt;
Begin
result := 0;
dgt := 1;
NUD := NUD SHR 1;
repeat
IF NUD AND 1 <> 0 then
Begin
If pI^.numNormal*pJ^.numUnusedDigit[dgt] = pJ^.numNormal*pI^.numUnusedDigit[dgt] then
Begin
inc(result);
inc(DigitCnt[dgt]);
IF Anzahl < 110 then
OutErg(dgt,pI,pJ);
end;
end;
inc(dgt);
NUD := NUD SHR 1;
until NUD = 0;
end;
procedure CheckWithOne(pI : tpErg;j,Nud:Uint32);
var
pJ : tpErg;
l : NativeUInt;
Begin
pJ := pI;
if UsedDigits <5 then
Begin
for j := j+1 to permcnt do
begin
inc(pJ);
//digits used by both numbers
l := NUD AND pJ^.numUsedDigits;
IF l <> 0 then
inc(Anzahl,Check(pI,pJ,l));
end;
end
else
Begin
for j := j+1 to permcnt do
begin
inc(pJ);
l := NUD AND pJ^.numUsedDigits;
inc(Anzahl,Check(pI,pJ,l));
end;
end;
end;
procedure SearchMultiple;
var
pI : tpErg;
i : NativeUInt;
begin
pI := @Erg[0];
for i := 0 to permcnt do
Begin
CheckWithOne(pI,i,pI^.numUsedDigits);
inc(pI);
end;
end;
function BinomCoeff(n, k: byte): longint;
var
i: longint;
begin
{n ueber k = n ueber (n-k) , also kuerzere Version waehlen}
if k > n div 2 then
k := n - k;
Result := 1;
if k <= n then
for i := 1 to k do
Result := Result * (n - i + 1) div i;{geht immer ohne Rest }
end;
procedure InsertToErg(var E: tErg; const x: tPermfield);
var
n : Uint64;
k,i,j,dgt,nud: NativeInt;
begin
// k of PermKoutofN is reduced by one for 9 digits
k := UsedDigits;
n := 0;
nud := 0;
for i := 1 to k do
begin
dgt := x[i];
nud := nud or cMaskDgt[dgt];
n := n * 10 + dgt;
end;
with E do
begin
numUsedDigits := nud;
numNormal := n;
end;
//calc all numbers with one removed digit
For J := k downto 1 do
Begin
n := 0;
for i := 1 to j-1 do
n := n * 10 + x[i];
for i := j+1 to k do
n := n * 10 + x[i];
E.numUnusedDigit[x[j]] := n;
end;
end;
procedure PermKoutofN(k, n: nativeInt);
var
x, y: tpPermfield;
i, yi, tmp: NativeInt;
begin
//initialise
x := @pf_x;
y := @pf_y;
permcnt := 0;
if k > n then
k := n;
if k = n then
k := k - 1;
for i := 1 to n do
x^[i] := i;
for i := 1 to k do
y^[i] := i;
InserttoErg(Erg[permcnt], x^);
i := k;
repeat
yi := y^[i];
if yi < n then
begin
Inc(permcnt);
Inc(yi);
y^[i] := yi;
tmp := x^[i];
x^[i] := x^[yi];
x^[yi] := tmp;
i := k;
InserttoErg(Erg[permcnt], x^);
end
else
begin
repeat
tmp := x^[i];
x^[i] := x^[yi];
x^[yi] := tmp;
Dec(yi);
until yi <= i;
y^[i] := yi;
Dec(i);
end;
until (i = 0);
end;
procedure OutDigitCount;
var
i : tDigit;
Begin
writeln('omitted digits 1 to 9');
For i := 1 to 9do
write(DigitCnt[i]:UsedDigits);
writeln;
end;
procedure ClearDigitCount;
var
i : tDigit;
Begin
For i := low(DigitCnt) to high(DigitCnt) do
DigitCnt[i] := 0;
end;
var
t1, t0: TDateTime;
begin
For UsedDigits := 8 to 9 do
Begin
writeln('Used digits ',UsedDigits);
T0 := now;
ClearDigitCount;
setlength(Erg, Fakultaet(UsedDigits) * BinomCoeff(cMaxDigits, UsedDigits));
Anzahl := 0;
permcnt := 0;
PermKoutOfN(UsedDigits, cMaxDigits);
SearchMultiple;
T1 := now;
writeln('Found solutions ',Anzahl);
OutDigitCount;
writeln('time taken ',FormatDateTime('HH:NN:SS.zzz', T1 - T0));
setlength(Erg, 0);
writeln;
end;
end.

View file

@ -0,0 +1,38 @@
use strict;
use warnings;
use feature 'say';
use List::Util qw<sum uniq uniqnum head tail>;
for my $exp (map { $_ - 1 } <2 3 4>) {
my %reduced;
my $start = sum map { 10 ** $_ * ($exp - $_ + 1) } 0..$exp;
my $end = 10**($exp+1) - -1 + sum map { 10 ** $_ * ($exp - $_) } 0..$exp-1;
for my $den ($start .. $end-1) {
next if $den =~ /0/ or (uniqnum split '', $den) <= $exp;
for my $num ($start .. $den-1) {
next if $num =~ /0/ or (uniqnum split '', $num) <= $exp;
my %i;
map { $i{$_}++ } (uniq head -1, split '',$den), uniq tail -1, split '',$num;
my @set = grep { $_ if $i{$_} > 1 } keys %i;
next if @set < 1;
for (@set) {
(my $ne = $num) =~ s/$_//;
(my $de = $den) =~ s/$_//;
if ($ne/$de == $num/$den) {
$reduced{"$num/$den:$_"} = "$ne/$de";
}
}
}
}
my $digit = $exp + 1;
say "\n" . +%reduced . " $digit-digit reducible fractions:";
for my $n (1..9) {
my $cnt = scalar grep { /:$n/ } keys %reduced;
say "$cnt with removed $n" if $cnt;
}
say "\n 12 (or all, if less) $digit-digit reducible fractions:";
for my $f (head 12, sort keys %reduced) {
printf " %s => %s removed %s\n", substr($f,0,$digit*2+1), $reduced{$f}, substr($f,-1)
}
}

View file

@ -0,0 +1,84 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">to_n</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">remove_digit</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">remove_digit</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">remove_digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">..</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">*</span><span style="color: #000000;">10</span><span style="color: #0000FF;">+</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">ndigits</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- generate numbers with unique digits efficiently
-- and store them in an array for multiple re-use,
-- along with an array of the removed-digit values.</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">used</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">-</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">used</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">used</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">to_n</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">to_n</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">),</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">used</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">used</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">used</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">used</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">j</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">used</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">used</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
<span style="color: #000080;font-style:italic;">--for n=2 to 6 do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndigits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">omitted</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">xn</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">rn</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">xd</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">rd</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">yn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">yd</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">yn</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">yd</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">xn</span><span style="color: #0000FF;">/</span><span style="color: #000000;">xd</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">yn</span><span style="color: #0000FF;">/</span><span style="color: #000000;">yd</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">omitted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">12</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d/%d =&gt; %d/%d (removed %d)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">xn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()></span><span style="color: #000000;">t1</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"working (%d/%d)...\r"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)})</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d-digit fractions found:%d, omitted %v\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">,</span><span style="color: #000000;">omitted</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--

View file

@ -0,0 +1,87 @@
def indexOf(haystack, needle):
idx = 0
for straw in haystack:
if straw == needle:
return idx
else:
idx += 1
return -1
def getDigits(n, le, digits):
while n > 0:
r = n % 10
if r == 0 or indexOf(digits, r) >= 0:
return False
le -= 1
digits[le] = r
n = int(n / 10)
return True
def removeDigit(digits, le, idx):
pows = [1, 10, 100, 1000, 10000]
sum = 0
pow = pows[le - 2]
i = 0
while i < le:
if i == idx:
i += 1
continue
sum = sum + digits[i] * pow
pow = int(pow / 10)
i += 1
return sum
def main():
lims = [ [ 12, 97 ], [ 123, 986 ], [ 1234, 9875 ], [ 12345, 98764 ] ]
count = [0 for i in range(5)]
omitted = [[0 for i in range(10)] for j in range(5)]
i = 0
while i < len(lims):
n = lims[i][0]
while n < lims[i][1]:
nDigits = [0 for k in range(i + 2)]
nOk = getDigits(n, i + 2, nDigits)
if not nOk:
n += 1
continue
d = n + 1
while d <= lims[i][1] + 1:
dDigits = [0 for k in range(i + 2)]
dOk = getDigits(d, i + 2, dDigits)
if not dOk:
d += 1
continue
nix = 0
while nix < len(nDigits):
digit = nDigits[nix]
dix = indexOf(dDigits, digit)
if dix >= 0:
rn = removeDigit(nDigits, i + 2, nix)
rd = removeDigit(dDigits, i + 2, dix)
if (1.0 * n / d) == (1.0 * rn / rd):
count[i] += 1
omitted[i][digit] += 1
if count[i] <= 12:
print "%d/%d = %d/%d by omitting %d's" % (n, d, rn, rd, digit)
nix += 1
d += 1
n += 1
print
i += 1
i = 2
while i <= 5:
print "There are %d %d-digit fractions of which:" % (count[i - 2], i)
j = 1
while j <= 9:
if omitted[i - 2][j] == 0:
j += 1
continue
print "%6s have %d's omitted" % (omitted[i - 2][j], j)
j += 1
print
i += 1
return None
main()

View file

@ -0,0 +1,43 @@
/*REXX pgm reduces fractions by "crossing out" matching digits in nominator&denominator.*/
parse arg high show . /*obtain optional arguments from the CL*/
if high=='' | high=="," then high= 4 /*Not specified? Then use the default.*/
if show=='' | show=="," then show= 12 /* " " " " " " */
say center(' some samples of reduced fractions by crossing out digits ', 79, "")
$.=0 /*placeholder array for counts; init. 0*/
do L=2 to high; say /*do 2-dig fractions to HIGH-dig fract.*/
lim= 10**L - 1 /*calculate the upper limit just once. */
do n=10**(L-1) to lim /*generate some N digit fractions. */
if pos(0, n) \==0 then iterate /*Does it have a zero? Then skip it.*/
if hasDup(n) then iterate /* " " " " dup? " " " */
do d=n+1 to lim /*only process like-sized #'s */
if pos(0, d)\==0 then iterate /*Have a zero? Then skip it. */
if verify(d, n, 'M')==0 then iterate /*No digs in common? Skip it.*/
if hasDup(d) then iterate /*Any digs are dups? " " */
q= n/d /*compute quotient just once. */
do e=1 for L; xo= substr(n, e, 1) /*try crossing out each digit.*/
nn= space( translate(n, , xo), 0) /*elide from the numerator. */
dd= space( translate(d, , xo), 0) /* " " " denominator. */
if nn/dd \== q then iterate /*Not the same quotient? Skip.*/
$.L= $.L + 1 /*Eureka! We found one. */
$.L.xo= $.L.xo + 1 /*count the silly reduction. */
if $.L>show then iterate /*Too many found? Don't show.*/
say center(n'/'d " = " nn'/'dd " by crossing out the" xo"'s.", 79)
end /*e*/
end /*d*/
end /*n*/
end /*L*/
say; @with= ' with crossed-out' /* [↓] show counts for any reductions.*/
do k=1 for 9 /*traipse through each cross─out digit.*/
if $.k==0 then iterate /*Is this a zero count? Then skip it. */
say; say center('There are ' $.k " "k'-digit fractions.', 79, "")
@for= ' For ' /*literal for SAY indentation (below). */
do #=1 for 9; if $.k.#==0 then iterate
say @for k"-digit fractions, there are " right($.k.#, k-1) @with #"'s."
end /*#*/
end /*k*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
hasDup: parse arg x; /* if L<2 then return 0 */ /*L will never be 1.*/
do i=1 for L-1; if pos(substr(x,i,1), substr(x,i+1)) \== 0 then return 1
end /*i*/; return 0

View file

@ -0,0 +1,60 @@
#lang racket
(require racket/generator
syntax/parse/define)
(define-syntax-parser for**
[(_ [x:id {~datum <-} (e ...)] rst ...) #'(e ... (λ (x) (for** rst ...)))]
[(_ e ...) #'(begin e ...)])
(define (permutations xs n yield #:lower [lower #f])
(let loop ([xs xs] [n n] [acc '()] [lower lower])
(cond
[(= n 0) (yield (reverse acc))]
[else (for ([x (in-list xs)] #:when (or (not lower) (>= x (first lower))))
(loop (remove x xs)
(sub1 n)
(cons x acc)
(and lower (= x (first lower)) (rest lower))))])))
(define (list->number xs) (foldl (λ (e acc) (+ (* 10 acc) e)) 0 xs))
(define (calc n)
(define rng (range 1 10))
(in-generator
(for** [numer <- (permutations rng n)]
[denom <- (permutations rng n #:lower numer)]
(for* (#:when (not (equal? numer denom))
[crossed (in-list numer)]
#:when (member crossed denom)
[numer* (in-value (list->number (remove crossed numer)))]
[denom* (in-value (list->number (remove crossed denom)))]
[numer** (in-value (list->number numer))]
[denom** (in-value (list->number denom))]
#:when (= (* numer** denom*) (* numer* denom**)))
(yield (list numer** denom** numer* denom* crossed))))))
(define (enumerate n)
(for ([x (calc n)] [i (in-range 12)])
(apply printf "~a/~a = ~a/~a (~a crossed out)\n" x))
(newline))
(define (stats n)
(define digits (make-hash))
(for ([x (calc n)]) (hash-update! digits (last x) add1 0))
(printf "There are ~a ~a-digit fractions of which:\n" (for/sum ([(k v) (in-hash digits)]) v) n)
(for ([digit (in-list (sort (hash->list digits) < #:key car))])
(printf " The digit ~a was crossed out ~a times\n" (car digit) (cdr digit)))
(newline))
(define (main)
(enumerate 2)
(enumerate 3)
(enumerate 4)
(enumerate 5)
(stats 2)
(stats 3)
(stats 4)
(stats 5))
(main)

View file

@ -0,0 +1,44 @@
my %reduced;
my $digits = 2..4;
for $digits.map: * - 1 -> $exp {
my $start = sum (0..$exp).map( { 10 ** $_ * ($exp - $_ + 1) });
my $end = 10**($exp+1) - sum (^$exp).map( { 10 ** $_ * ($exp - $_) } ) - 1;
($start ..^ $end).race(:8degree, :3batch).map: -> $den {
next if $den.contains: '0';
next if $den.comb.unique <= $exp;
for $start ..^ $den -> $num {
next if $num.contains: '0';
next if $num.comb.unique <= $exp;
my $set = ($den.comb.head(* - 1).Set $num.comb.skip(1).Set);
next if $set.elems < 1;
for $set.keys {
my $ne = $num.trans: $_ => '', :delete;
my $de = $den.trans: $_ => '', :delete;
if $ne / $de == $num / $den {
print "\b" x 40, "$num/$den:$_ => $ne/$de";
%reduced{"$num/$den:$_"} = "$ne/$de";
}
}
}
}
print "\b" x 40, ' ' x 40, "\b" x 40;
my $digit = $exp +1;
my %d = %reduced.pairs.grep: { .key.chars == ($digit * 2 + 3) };
say "\n({+%d}) $digit digit reduceable fractions:";
for 1..9 {
my $cnt = +%d.pairs.grep( *.key.contains: ":$_" );
next unless $cnt;
say " $cnt with removed $_";
}
say "\n 12 Random (or all, if less) $digit digit reduceable fractions:";
say " {.key.substr(0, $digit * 2 + 1)} => {.value} removed {.key.substr(* - 1)}"
for %d.pairs.pick(12).sort;
}

View file

@ -0,0 +1,108 @@
def indexOf(haystack, needle)
idx = 0
for straw in haystack
if straw == needle then
return idx
else
idx = idx + 1
end
end
return -1
end
def getDigits(n, le, digits)
while n > 0
r = n % 10
if r == 0 or indexOf(digits, r) >= 0 then
return false
end
le = le - 1
digits[le] = r
n = (n / 10).floor
end
return true
end
POWS = [1, 10, 100, 1000, 10000]
def removeDigit(digits, le, idx)
sum = 0
pow = POWS[le - 2]
i = 0
while i < le
if i == idx then
i = i + 1
next
end
sum = sum + digits[i] * pow
pow = (pow / 10).floor
i = i + 1
end
return sum
end
def main
lims = [ [ 12, 97 ], [ 123, 986 ], [ 1234, 9875 ], [ 12345, 98764 ] ]
count = Array.new(5, 0)
omitted = Array.new(5) { Array.new(10, 0) }
i = 0
for lim in lims
n = lim[0]
while n < lim[1]
nDigits = [0] * (i + 2)
nOk = getDigits(n, i + 2, nDigits)
if not nOk then
n = n + 1
next
end
d = n + 1
while d <= lim[1] + 1
dDigits = [0] * (i + 2)
dOk = getDigits(d, i + 2, dDigits)
if not dOk then
d = d + 1
next
end
nix = 0
while nix < nDigits.length
digit = nDigits[nix]
dix = indexOf(dDigits, digit)
if dix >= 0 then
rn = removeDigit(nDigits, i + 2, nix)
rd = removeDigit(dDigits, i + 2, dix)
if (1.0 * n / d) == (1.0 * rn / rd) then
count[i] = count[i] + 1
omitted[i][digit] = omitted[i][digit] + 1
if count[i] <= 12 then
print "%d/%d = %d/%d by omitting %d's\n" % [n, d, rn, rd, digit]
end
end
end
nix = nix + 1
end
d = d + 1
end
n = n + 1
end
print "\n"
i = i + 1
end
i = 2
while i <= 5
print "There are %d %d-digit fractions of which:\n" % [count[i - 2], i]
j = 1
while j <= 9
if omitted[i - 2][j] == 0 then
j = j + 1
next
end
print "%6s have %d's omitted\n" % [omitted[i - 2][j], j]
j = j + 1
end
print "\n"
i = i + 1
end
end
main()

View file

@ -0,0 +1,96 @@
Module Module1
Function IndexOf(n As Integer, s As Integer()) As Integer
For ii = 1 To s.Length
Dim i = ii - 1
If s(i) = n Then
Return i
End If
Next
Return -1
End Function
Function GetDigits(n As Integer, le As Integer, digits As Integer()) As Boolean
While n > 0
Dim r = n Mod 10
If r = 0 OrElse IndexOf(r, digits) >= 0 Then
Return False
End If
le -= 1
digits(le) = r
n \= 10
End While
Return True
End Function
Function RemoveDigit(digits As Integer(), le As Integer, idx As Integer) As Integer
Dim pows = {1, 10, 100, 1000, 10000}
Dim sum = 0
Dim pow = pows(le - 2)
For ii = 1 To le
Dim i = ii - 1
If i = idx Then
Continue For
End If
sum += digits(i) * pow
pow \= 10
Next
Return sum
End Function
Sub Main()
Dim lims = {{12, 97}, {123, 986}, {1234, 9875}, {12345, 98764}}
Dim count(5) As Integer
Dim omitted(5, 10) As Integer
Dim upperBound = lims.GetLength(0)
For ii = 1 To upperBound
Dim i = ii - 1
Dim nDigits(i + 2 - 1) As Integer
Dim dDigits(i + 2 - 1) As Integer
Dim blank(i + 2 - 1) As Integer
For n = lims(i, 0) To lims(i, 1)
blank.CopyTo(nDigits, 0)
Dim nOk = GetDigits(n, i + 2, nDigits)
If Not nOk Then
Continue For
End If
For d = n + 1 To lims(i, 1) + 1
blank.CopyTo(dDigits, 0)
Dim dOk = GetDigits(d, i + 2, dDigits)
If Not dOk Then
Continue For
End If
For nixt = 1 To nDigits.Length
Dim nix = nixt - 1
Dim digit = nDigits(nix)
Dim dix = IndexOf(digit, dDigits)
If dix >= 0 Then
Dim rn = RemoveDigit(nDigits, i + 2, nix)
Dim rd = RemoveDigit(dDigits, i + 2, dix)
If (n / d) = (rn / rd) Then
count(i) += 1
omitted(i, digit) += 1
If count(i) <= 12 Then
Console.WriteLine("{0}/{1} = {2}/{3} by omitting {4}'s", n, d, rn, rd, digit)
End If
End If
End If
Next
Next
Next
Console.WriteLine()
Next
For i = 2 To 5
Console.WriteLine("There are {0} {1}-digit fractions of which:", count(i - 2), i)
For j = 1 To 9
If omitted(i - 2, j) = 0 Then
Continue For
End If
Console.WriteLine("{0,6} have {1}'s omitted", omitted(i - 2, j), j)
Next
Console.WriteLine()
Next
End Sub
End Module

View file

@ -0,0 +1,87 @@
import "/dynamic" for Struct
import "/fmt" for Fmt
var Result = Struct.create("Result", ["n", "nine"])
var toNumber = Fn.new { |digits, removeDigit|
var digits2 = digits.toList
if (removeDigit != 0) {
var d = digits2.indexOf(removeDigit)
digits2.removeAt(d)
}
var res = digits2[0]
var i = 1
while (i < digits2.count) {
res = res * 10 + digits2[i]
i = i + 1
}
return res
}
var nDigits = Fn.new { |n|
var res = []
var digits = List.filled(n, 0)
var used = List.filled(9, false)
for (i in 0...n) {
digits[i] = i + 1
used[i] = true
}
while (true) {
var nine = List.filled(9, 0)
for (i in 0...used.count) {
if (used[i]) nine[i] = toNumber.call(digits, i+1)
}
res.add(Result.new(toNumber.call(digits, 0), nine))
var found = false
for (i in n-1..0) {
var d = digits[i]
if (!used[d-1]) {
Fiber.abort("something went wrong with 'used' array")
}
used[d-1] = false
var j = d
while (j < 9) {
if (!used[j]) {
used[j] = true
digits[i] = j + 1
for (k in i + 1...n) {
digits[k] = used.indexOf(false) + 1
used[digits[k]-1] = true
}
found = true
break
}
j = j + 1
}
if (found) break
}
if (!found) break
}
return res
}
for (n in 2..5) {
var rs = nDigits.call(n)
var count = 0
var omitted = List.filled(9, 0)
for (i in 0...rs.count-1) {
var xn = rs[i].n
var rn = rs[i].nine
for (j in i + 1...rs.count) {
var xd = rs[j].n
var rd = rs[j].nine
for (k in 0..8) {
var yn = rn[k]
var yd = rd[k]
if (yn != 0 && yd != 0 && xn/xd == yn/yd) {
count = count + 1
omitted[k] = omitted[k] + 1
if (count <= 12) {
Fmt.print("$d/$d => $d/$d (removed $d)", xn, xd, yn, yd, k+1)
}
}
}
}
}
Fmt.print("$d-digit fractions found:$d, omitted $s\n", n, count, omitted)
}

View file

@ -0,0 +1,59 @@
fcn toInt(digits,remove_digit=0){
if(remove_digit!=0) digits=digits.copy().del(digits.index(remove_digit));
digits.reduce(fcn(s,d){ s*10 + d });
}
fcn nDigits(n){
//-- generate numbers with unique digits efficiently
//-- and store them in an array for multiple re-use,
//-- along with an array of the removed-digit values.
res,digits := List(), n.pump(List(),'+(1)); // 1,2,3,4..n
used := List.createLong(n,1).extend(List.createLong(9-n,0));
while(True){
nine:=List.createLong(9,0);
foreach i in (used.len()){ if(used[i]) nine[i]=toInt(digits,i+1) }
res.append(T(toInt(digits),nine));
found:=False;
foreach i in ([n-1..0, -1]){
d:=digits[i];
if(not used[d-1]) println("ack!");
used[d-1]=0;
foreach j in ([d..8]){
if(not used[j]){
used[j]=1;
digits[i]=j+1;
foreach k in ([i+1..n-1]){
digits[k] = used.find(0) + 1;
used[digits[k] - 1]=1;
}
found=True;
break;
}
}
if(found) break;
}//foreach i
if(not found) break;
}//while
res
}
foreach n in ([2..5]){
rs,rsz,count,omitted := nDigits(n),rs.len()-1, 0, List.createLong(9,0);
foreach i in (rsz){
xn,rn := rs[i];
foreach j in ([i+1..rsz]){
xd,rd := rs[j];
foreach k in ([0..8]){
yn,yd := rn[k],rd[k];
if(yn!=0 and yd!=0 and
xn.toFloat()/xd.toFloat() == yn.toFloat()/yd.toFloat()){
count+=1;
omitted[k]+=1;
if(count<=12)
println("%d/%d --> %d/%d (removed %d)".fmt(xn,xd,yn,yd,k+1));
}
}
}
}
println("%d-digit fractions found: %d, omitted %s\n"
.fmt(n,count,omitted.concat(",")));
}