Skip to content

Instantly share code, notes, and snippets.

@Mercerenies
Last active September 8, 2020 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mercerenies/b980752a4b6008ac8b5700b0cd2a899f to your computer and use it in GitHub Desktop.
Save Mercerenies/b980752a4b6008ac8b5700b0cd2a899f to your computer and use it in GitHub Desktop.
% Sadly, GitHub doesn't seem to support syntax highlighting for
% Potassco :(
%
% There's an Emacs mode for it if you want to see this file pretty.
% See the Perl script below for instructions on how to run this.
ispos(1..N) :- length(N).
isdigit(0..N) :- length(N).
pos(P, N) :- ispos(P), isdigit(N), not not pos(P, N).
{ pos(P, N) : isdigit(N) } = 1 :- ispos(P).
% Distinct digits.
hasdigit(N) :- ispos(P), pos(P, N).
pos(1, N) :- isdigit(N), { hasdigit(M) : isdigit(M) } = N.
% Counting digits.
countdigit(N, I) :- isdigit(N), isdigit(I), { pos(P, N) : ispos(P) } = I.
pos(P, I) :- ispos(P), P > 0, N = P - 2, countdigit(N, I).
#show pos/2.
% Sadly, GitHub doesn't seem to support syntax highlighting for
% Potassco :(
%
% There's an Emacs mode for it if you want to see this file pretty.
ispos(1..N) :- length(N).
isdigit(0..N) :- length(N).
pos(P, N) :- ispos(P), isdigit(N), not not pos(P, N).
{ pos(P, N) : isdigit(N) } = 1 :- ispos(P).
% Distinct digits.
hasdigit(N) :- ispos(P), pos(P, N).
pos(1, N) :- isdigit(N), { hasdigit(M) : isdigit(M) } = N.
% Counting digits.
countdigit(N, I) :- isdigit(N), isdigit(I), { pos(P, N) : ispos(P) } = I.
pos(P, I) :- ispos(P), P > 0, N = P - 2, countdigit(N, I).
#show pos/2.
#!/usr/bin/env perl
# More efficient fixed-point finder compared to my earlier attempt.
#
# * First attempt: https://gist.github.com/Mercerenies/4a3297eeeeffc64da5489891450374d1
# * Context: https://math.stackexchange.com/questions/3816844/why-the-self-referential-number-function-eventually-fixes-every-point
#
# Make sure clingo (https://potassco.org/clingo/) is on your path, put
# this file and the selfref.lp file in the same directory, and then
# simply run this Perl script with no arguments to find all fixed
# points for n up to 30.
use strict;
use warnings;
use 5.010;
use autodie;
use File::Temp qw(tempfile cleanup);
use Fcntl qw(SEEK_SET);
use IO::Handle;
sub process_output {
my $len = shift;
my $line = shift;
my @data;
for my $i (1..$len) {
$line =~ /pos\($i,\s*(\d+)\)/ or die("Invalid output");
push @data, $1;
}
local $" = " ";
say "@data";
}
sub run_with_length {
my $tmpfile = shift;
my $tmpfh = shift;
my $len = shift;
seek($tmpfh, 0, SEEK_SET);
say $tmpfh "length($len).\n\n";
open(my $fh, '<', 'selfref.lp');
while (<$fh>) {
print $tmpfh $_;
}
close($fh);
$tmpfh->flush();
open(my $outfh, '-|', "clingo $tmpfile 0");
while (<$outfh>) {
if (/^Answer: \d+/) {
my $next = <$outfh>;
chomp $next;
process_output($len, $next);
}
}
}
my ($tmpfh, $tmpfile) = tempfile('selfrefXXXX', suffix => '.txt', CLEANUP => 1);
for my $i (1..30) {
say "Running for $i...";
run_with_length($tmpfile, $tmpfh, $i);
}
cleanup();
END {
`rm $tmpfile`;
}
Running for 1...
1
Running for 2...
Running for 3...
Running for 4...
Running for 5...
4 1 2 1 0
Running for 6...
4 1 3 0 1 1
4 1 2 2 0 1
Running for 7...
3 3 0 2 2 0 0
3 3 1 0 3 0 0
Running for 8...
5 2 3 1 1 0 1 0
Running for 9...
4 4 1 2 0 2 0 0 0
5 3 2 2 1 0 1 0 0
Running for 10...
5 4 3 0 1 1 1 0 0 0
5 4 2 2 0 1 1 0 0 0
Running for 11...
Running for 12...
5 6 3 0 1 0 1 1 0 0 0 0
5 6 2 2 0 0 1 1 0 0 0 0
Running for 13...
5 7 3 0 1 0 1 0 1 0 0 0 0
5 7 2 2 0 0 1 0 1 0 0 0 0
Running for 14...
5 8 2 2 0 0 1 0 0 1 0 0 0 0
5 8 3 0 1 0 1 0 0 1 0 0 0 0
Running for 15...
5 9 3 0 1 0 1 0 0 0 1 0 0 0 0
5 9 2 2 0 0 1 0 0 0 1 0 0 0 0
Running for 16...
5 10 2 2 0 0 1 0 0 0 0 1 0 0 0 0
5 10 3 0 1 0 1 0 0 0 0 1 0 0 0 0
Running for 17...
5 11 2 2 0 0 1 0 0 0 0 0 1 0 0 0 0
5 11 3 0 1 0 1 0 0 0 0 0 1 0 0 0 0
Running for 18...
5 12 2 2 0 0 1 0 0 0 0 0 0 1 0 0 0 0
5 12 3 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0
Running for 19...
5 13 2 2 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
5 13 3 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0
Running for 20...
5 14 3 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0
5 14 2 2 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 21...
5 15 2 2 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 15 3 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 22...
5 16 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 16 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 23...
5 17 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 17 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 24...
5 18 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 18 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 25...
5 19 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 19 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 26...
5 20 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 20 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 27...
5 21 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 21 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 28...
5 22 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 22 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 29...
5 23 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 23 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Running for 30...
5 24 3 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
5 24 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment