Self-describing numbers: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(18 intermediate revisions by 9 users not shown)
Line 31:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F is_self_describing(n)
V s = String(n)
R all(enumerate(Array(s)).map((i, ch) -> @s.count(String(i)) == Int(ch)))
 
print((0.<4000000).filter(x -> is_self_describing(x)))</langsyntaxhighlight>
 
{{out}}
Line 43:
 
=={{header|360 Assembly}}==
<langsyntaxhighlight lang="360asm">* Self-describing numbers 26/04/2020
SELFDESC CSECT
USING SELFDESC,R13 base register
Line 106:
XDEC DS CL12 temp fo xdeco
REGEQU
END SELFDESC </langsyntaxhighlight>
{{out}}
<pre>
Line 116:
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
procedure SelfDesc is
subtype Desc_Int is Long_Integer range 0 .. 10**10-1;
Line 140:
end if;
end loop;
end SelfDesc;</langsyntaxhighlight>
{{out}}
<pre>1210
Line 151:
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
{{works with|ALGOL 68G|Any - tested with release 2.6.win32}}
<langsyntaxhighlight lang="algol68">BEGIN
 
# return TRUE if number is self describing, FALSE otherwise #
Line 196:
)
 
END</langsyntaxhighlight>
{{out}}
<pre>
Line 207:
 
=={{header|AppleScript}}==
<langsyntaxhighlight lang="applescript">use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
Line 400:
set my text item delimiters to dlm
s
end unlines</langsyntaxhighlight>
{{Out}}
<pre>1210 -> true
Line 410:
3211000 -> true
3211004 -> false</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">selfDescribing?: function [x][
digs: digits x
loop.with:'i digs 'd [
if d <> size select digs 'z [z=i]
-> return false
]
return true
]
 
print select 1..22000 => selfDescribing?</syntaxhighlight>
 
{{out}}
 
<pre>1210 2020 21200</pre>
 
=={{header|AutoHotkey}}==
Uses CountSubString: [[Count occurrences of a substring#AutoHotkey]]
<langsyntaxhighlight AutoHotkeylang="autohotkey">; The following directives and commands speed up execution:
#NoEnv
SetBatchlines -1
Line 435 ⟶ 452:
return false
return true
}</langsyntaxhighlight>
Output:
<pre>---------------------------
Line 452 ⟶ 469:
 
=={{header|AWK}}==
<langsyntaxhighlight AWKlang="awk"># syntax: GAWK -f SELF-DESCRIBING_NUMBERS.AWK
BEGIN {
for (n=1; n<=100000000; n++) {
Line 468 ⟶ 485:
}
return(1)
}</langsyntaxhighlight>
<p>output:</p>
<pre>
Line 479 ⟶ 496:
 
=={{header|BASIC}}==
<langsyntaxhighlight lang="qbasic">Dim x, r, b, c, n, m As Integer
Dim a, d As String
Dim v(10), w(10) As Integer
Line 502 ⟶ 519:
Print "End"
sleep
end</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> FOR N = 1 TO 5E7
IF FNselfdescribing(N) PRINT N
NEXT
Line 521 ⟶ 538:
N% DIV=10
ENDWHILE
= O% = SUM(D%())</langsyntaxhighlight>
Output:
<pre>
Line 536 ⟶ 553:
Be aware, though, that even with a fast interpreter, it's going to be a very long time before you see the full set of results.
 
<langsyntaxhighlight lang="befunge">>1+9:0>\#06#:p#-:#1_$v
?v6:%+55:\+1\<<<\0:::<
#>g1+\6p55+/:#^_001p\v
^_@#!`<<v\+g6g10*+55\<
>:*:*:*^>>:01g1+:01p`|
^_\#\:#+.#5\#5,#$:<-$<</langsyntaxhighlight>
 
{{out}}
Line 552 ⟶ 569:
=={{header|C}}==
Using integers instead of strings.
<langsyntaxhighlight lang="c">#include <stdio.h>
 
inline int self_desc(unsigned long long xx)
Line 577 ⟶ 594:
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text">1210
2020
21200
3211000
42101000</langsyntaxhighlight>
 
===Backtracking version===
Backtracks on each digit from right to left, takes advantage of constraints "sum of digit values = number of digits" and "sum of (digit index * digit value) = number of digits". It is using as argument the list of allowed digits (example 012345789 to run the program in standard base 10).
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 678 ⟶ 695:
puts("");
}
}</langsyntaxhighlight>
 
Output for base 36
<syntaxhighlight lang="text">$ time ./selfdesc.exe 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
1210
2020
Line 718 ⟶ 735:
real 0m0.094s
user 0m0.046s
sys 0m0.030s</langsyntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <iostream>
Line 795 ⟶ 812:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 810 ⟶ 827:
Uses C++11. Build with
g++ -std=c++11 sdn.cpp
<langsyntaxhighlight lang="cpp">#include <algorithm>
#include <array>
#include <iostream>
Line 835 ⟶ 852:
}
}
}</langsyntaxhighlight>
Output:
<pre>
Line 846 ⟶ 863:
6210001000
</pre>
 
=={{header|CLU}}==
<syntaxhighlight lang="clu">self_describing = proc (n: int) returns (bool)
digits: array[int] := array[int]$predict(10, 10)
counts: array[int] := array[int]$fill(0, 10, 0)
 
while n > 0 do
digit: int := n // 10
n := n/10
array[int]$addl(digits, digit)
counts[digit] := counts[digit] + 1
end
 
array[int]$set_low(digits, 0)
 
for pos: int in array[int]$indexes(digits) do
if counts[pos] ~= digits[pos] then return(false) end
end
return(true)
end self_describing
 
start_up = proc ()
po: stream := stream$primary_output()
for n: int in int$from_to(1, 100000000) do
if self_describing(n) then
stream$putl(po, int$unparse(n))
end
end
end start_up</syntaxhighlight>
{{out}}
<pre>1210
2020
21200
3211000
42101000</pre>
 
=={{header|Common Lisp}}==
Line 853 ⟶ 905:
probably much faster because it wouldn't have to allocate an array and then
turn around and "interpret" it back out but I didn't really pursue it.
<langsyntaxhighlight lang="lisp">(defun to-ascii (str) (mapcar #'char-code (coerce str 'list)))
 
(defun to-digits (n)
Line 872 ⟶ 924:
(digits (to-digits n) (cdr digits)))
((null digits) t)
(if (not (eql (car digits) (aref counts ipos))) (return nil)))))</langsyntaxhighlight>
 
Output:
<syntaxhighlight lang="text">(loop for i from 1 to 4000000 do (if (self-described-p i) (print i)))
 
1210
Line 881 ⟶ 933:
21200
3211000
NIL</langsyntaxhighlight>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
sub Length(n: uint32): (l: uint8) is
l := 0;
while n > 0 loop
n := n/10;
l := l+1;
end loop;
end sub;
 
sub IsSelfDescribing(n: uint32): (r: uint8) is
var positions: uint8[10];
var digitCounts: uint8[10];
 
MemSet(&positions[0], 0, @bytesof positions);
MemSet(&digitCounts[0], 0, @bytesof digitCounts);
 
var pos: uint8 := Length(n) - 1;
while n > 0 loop
var digit := (n % 10) as uint8;
positions[pos] := digit;
digitCounts[digit] := digitCounts[digit] + 1;
pos := pos - 1;
n := n / 10;
end loop;
 
r := 1;
pos := 0;
while pos < 10 loop
if positions[pos] != digitCounts[pos] then
r := 0;
break;
end if;
pos := pos + 1;
end loop;
end sub;
 
var n: uint32 := 1;
while n < 100000000 loop
if IsSelfDescribing(n) != 0 then
print_i32(n);
print_nl();
end if;
n := n + 1;
end loop;</syntaxhighlight>
{{out}}
<pre>1210
2020
21200
3211000
42101000</pre>
 
=={{header|Crystal}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">def self_describing?(n)
digits = n.to_s.chars.map(&.to_i) # 12345 => [1, 2, 3, 4, 5]
digits.each_with_index.all? { |digit, idx| digits.count(idx) == digit }
Line 892 ⟶ 997:
t = Time.monotonic
600_000_000.times { |n| (puts "#{n} in #{(Time.monotonic - t).total_seconds} secs";\
t = Time.monotonic) if self_describing?(n) }</langsyntaxhighlight>
System: I7-6700HQ, 3.5 GHz, Linux Kernel 5.6.17, Crystal 0.35
Compil: $ crystal build selfdescribing.cr --release
Line 907 ⟶ 1,012:
 
{{trans|Wren and Go}}
<langsyntaxhighlight lang="ruby">def selfDesc(n)
ns = n.to_s
nc = ns.size
Line 956 ⟶ 1,061:
end
osecs = (Time.monotonic - start).total_seconds
print("\nTook #{osecs} secs overall")</langsyntaxhighlight>
 
System: I7-6700HQ, 3.5 GHz, Linux Kernel 5.6.17, Crystal 0.35
Line 973 ⟶ 1,078:
=={{header|D}}==
===Functional Version===
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.conv, std.string;
 
bool isSelfDescribing(in long n) pure nothrow @safe {
Line 982 ⟶ 1,087:
void main() {
4_000_000.iota.filter!isSelfDescribing.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>[1210, 2020, 21200, 3211000]</pre>
 
===A Faster Version===
<langsyntaxhighlight lang="d">bool isSelfDescribing2(ulong n) nothrow @nogc {
if (n <= 0)
return false;
Line 1,029 ⟶ 1,134:
if (i.isSelfDescribing2)
i.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>1210
Line 1,044 ⟶ 1,149:
42101000
521001000</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
{This routine would normally be in a library. It is shown here for clarity.}
 
 
procedure GetDigitsRev(N: integer; var IA: TIntegerDynArray);
{Get an array of the integers in a number}
{Numbers returned from most to least significant}
var T,I,DC: integer;
begin
DC:=Trunc(Log10(N))+1;
SetLength(IA,DC);
for I:=DC-1 downto 0 do
begin
T:=N mod 10;
N:=N div 10;
IA[I]:=T;
end;
end;
 
 
 
function IsSelfDescribing(N: integer): boolean;
var IA: TIntegerDynArray;
var CA: array [0..9] of integer;
var I: integer;
begin
{Get digits, High-low order}
GetDigitsRev(N,IA);
for I:=0 to High(CA) do CA[I]:=0;
{Count number of each digit 0..9}
for I:=0 to High(IA) do
begin
CA[IA[I]]:=CA[IA[I]]+1;
end;
Result:=False;
{Compare original number with counts}
for I:=0 to High(IA) do
if IA[I]<>CA[I] then exit;
Result:=True;
end;
 
 
procedure SelfDescribingNumbers(Memo: TMemo);
var I: integer;
begin
for I:=0 to 100000000-1 do
if IsSelfDescribing(I) then
begin
Memo.Lines.Add(IntToStr(I));
end;
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
1210
2020
21200
3211000
42101000
Elapsed Time: 23.584 Sec.
 
</pre>
 
 
=={{header|EasyLang}}==
Works with backtracking, iterative is too slow. Constraint: the sum of the digits count is the number of digits.
<syntaxhighlight lang="easylang">
proc test d[] . .
cnt[] = [ 0 0 0 0 0 0 0 0 0 0 ]
for d in d[]
cnt[d + 1] += 1
.
for i to len d[]
if cnt[i] <> d[i]
return
.
.
# found
for d in d[]
write d
.
print ""
.
proc backtr ind max . d[] .
if ind > len d[]
test d[]
return
.
for d = 0 to max
if d < 10
d[ind] = d
backtr ind + 1 max - d d[]
.
.
.
for i = 1 to 10
len d[] i
backtr 1 len d[] d[]
.
</syntaxhighlight>
{{out}}
<pre>
1210
2020
21200
3211000
42101000
521001000
6210001000
</pre>
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule Self_describing do
def number(n) do
digits = Integer.digits(n)
Line 1,056 ⟶ 1,279:
 
m = 3300000
Enum.filter(0..m, fn n -> Self_describing.number(n) end)</langsyntaxhighlight>
 
{{out}}
Line 1,065 ⟶ 1,288:
=={{header|Erlang}}==
 
<langsyntaxhighlight lang="erlang">
 
sdn(N) -> lists:map(fun(S)->length(lists:filter(fun(C)->C-$0==S end,N))+$0 end,lists:seq(0,length(N)-1))==N.
gen(M) -> lists:filter(fun(N)->sdn(integer_to_list(N)) end,lists:seq(0,M)).
 
</syntaxhighlight>
</lang>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: kernel math.parser prettyprint sequences ;
IN: rosetta-code.self-describing-numbers
 
Line 1,083 ⟶ 1,306:
digits dup [ digit-count = ] with map-index [ t = ] all? ;
 
100,000,000 <iota> [ self-describing-number? ] filter .</langsyntaxhighlight>
{{out}}
<pre>
Line 1,091 ⟶ 1,314:
=={{header|Forth}}==
 
<langsyntaxhighlight lang="forth">\ where unavailable.
: third ( A b c -- A b c A ) >r over r> swap ;
: (.) ( u -- c-addr u ) 0 <# #s #> ;
Line 1,106 ⟶ 1,329:
(.) [char] 0 third third bounds ?do
count i c@ [char] 0 - <> if drop 2drop false unloop exit then
loop drop 2drop true ;</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Function selfDescribing (n As UInteger) As Boolean
Line 1,131 ⟶ 1,354:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 1,141 ⟶ 1,364:
=={{header|Go}}==
===Original===
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,170 ⟶ 1,393:
}
}
}</langsyntaxhighlight>
Output produced by above program:
<pre>
Line 1,184 ⟶ 1,407:
===Optimized===
Uses the optimized loop from the Wren entry - 12 times faster than before.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,239 ⟶ 1,462:
osecs := time.Since(start).Seconds()
fmt.Printf("\nTook %.1f secs overall\n", osecs)
}</langsyntaxhighlight>
 
{{out}}
Line 1,257 ⟶ 1,480:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.Char
 
count :: Int -> [Int] -> Int
Line 1,273 ⟶ 1,496:
isSelfDescribing <$>
[1210, 2020, 21200, 3211000, 42101000, 521001000, 6210001000]
print $ filter isSelfDescribing [0 .. 4000000]</langsyntaxhighlight>
Output:
<pre>[True,True,True,True,True,True,True]
Line 1,279 ⟶ 1,502:
 
Here are functions for generating all the self-describing numbers of a certain length. We capitalize on the fact (from Wikipedia) that a self-describing number of length n is a base-n number (i.e. all digits are 0..n-1).
<langsyntaxhighlight lang="haskell">import Control.Monad (forM_, replicateM)
import Data.Char (intToDigit)
 
Line 1,308 ⟶ 1,531:
. filter isSelfDescribing
. allBaseNNumsOfLength
<$> [1 .. 8]</langsyntaxhighlight>
{{Out}}
<pre>[1210,2020,21200,3211000,42101000]</pre>
Line 1,316 ⟶ 1,539:
The following program contains the procedure <code>is_self_describing</code> to test if a number is a self-describing number, and the procedure <code>self_describing_numbers</code> to generate them.
 
<syntaxhighlight lang="icon">
<lang Icon>
procedure count (test_item, str)
result := 0
Line 1,345 ⟶ 1,568:
every write (self_describing_numbers ()\4)
end
</syntaxhighlight>
</lang>
A slightly more concise solution can be derived from the above by taking
more advantage of Icon's (and Unicon's) automatic goal-directed
evaluation:
<langsyntaxhighlight lang="unicon">
procedure is_self_describing (n)
ns := string (n) # convert to a string
Line 1,360 ⟶ 1,583:
procedure self_describing_numbers ()
suspend is_self_describing(seq())
end</langsyntaxhighlight>
 
=={{header|J}}==
 
'''Solution''':<langsyntaxhighlight lang="j"> digits =: 10&#.^:_1
counts =: _1 + [: #/.~ i.@:# , ]
selfdesc =: = counts&.digits"0 NB. Note use of "under"</langsyntaxhighlight>
'''Example''':<langsyntaxhighlight lang="j"> selfdesc 2020 1210 21200 3211000 43101000 42101000
1 1 1 1 0 1</langsyntaxhighlight>
'''Extra credit''':<langsyntaxhighlight lang="j"> I.@:selfdesc i. 1e6
1210 2020 21200</langsyntaxhighlight>
'''Discussion''': The use of <tt>&.</tt> here is a great example of its surprisingly broad applicability, and the elegance it can produce.
 
Line 1,380 ⟶ 1,603:
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">public class SelfDescribingNumbers{
public static boolean isSelfDescribing(int a){
String s = Integer.toString(a);
Line 1,406 ⟶ 1,629:
}
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
{{works with|SpiderMonkey}}
 
<langsyntaxhighlight lang="javascript">function is_self_describing(n) {
var digits = Number(n).toString().split("").map(function(elem) {return Number(elem)});
var len = digits.length;
Line 1,438 ⟶ 1,661:
for (var i=1; i<=3300000; i++)
if (is_self_describing(i))
print(i);</langsyntaxhighlight>
 
outputs
Line 1,448 ⟶ 1,671:
=={{header|jq}}==
{{works with|jq|1.4}}
<langsyntaxhighlight lang="jq"># If your jq includes all/2 then comment out the following definition,
# which is slightly less efficient:
def all(generator; condition):
reduce generator as $i (true; if . then $i | condition else . end);</langsyntaxhighlight>
<langsyntaxhighlight lang="jq">def selfie:
def count(value): reduce .[] as $i (0; if $i == value then . + 1 else . end);
def digits: tostring | explode | map(. - 48);
Line 1,460 ⟶ 1,683:
else . as $digits
| all ( range(0; length); . as $i | $digits | (.[$i] == count($i)) )
end;</langsyntaxhighlight>
'''The task:'''
<langsyntaxhighlight lang="jq">range(0; 100000001) | select(selfie)</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq -n -f Self-describing_numbers.jq
1210
2020
21200
3211000
42101000</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">function selfie(x::Integer)
ds = reverse(digits(x))
if sum(ds) != length(ds) return false end
Line 1,487 ⟶ 1,710:
 
selfies(x) = for i in 1:x selfie(i) && println(i) end
@time selfies(4000000)</langsyntaxhighlight>
 
{{out}}
Line 1,497 ⟶ 1,720:
 
=={{header|K}}==
<langsyntaxhighlight lang="k"> sdn: {n~+/'n=/:!#n:0$'$x}'
sdn 1210 2020 2121 21200 3211000 42101000
1 1 0 1 1 1
 
&sdn@!:1e6
1210 2020 21200</langsyntaxhighlight>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun selfDescribing(n: Int): Boolean {
Line 1,525 ⟶ 1,748:
for (i in 0..99999999) if (selfDescribing(i)) print("$i ")
println()
}</langsyntaxhighlight>
 
{{out}}
Line 1,534 ⟶ 1,757:
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">'adapted from BASIC solution
FOR x = 1 TO 5000000
a$ = TRIM$(STR$(x))
Line 1,552 ⟶ 1,775:
NEXT x
PRINT
PRINT "End"</langsyntaxhighlight>
 
=={{header|LiveCode}}==
<langsyntaxhighlight LiveCodelang="livecode">function selfDescNumber n
local tSelfD, tLen
put len(n) into tLen
Line 1,565 ⟶ 1,788:
end repeat
return tSelfD
end selfDescNumber</langsyntaxhighlight>
To list the self-describing numbers to 10 million<langsyntaxhighlight LiveCodelang="livecode">on mouseUp
repeat with n = 0 to 10000000
if selfDescNumber(n) then
Line 1,574 ⟶ 1,797:
combine selfNum using comma
put selfNum
end mouseUp</langsyntaxhighlight>
Output<syntaxhighlight lang LiveCode="livecode">1210,2020,21200,3211000</langsyntaxhighlight>
 
=={{header|Logo}}==
<langsyntaxhighlight lang="logo">TO XX
BT
MAKE "AA (ARRAY 10 0)
Line 1,603 ⟶ 1,826:
FOR [Z 0 9][SETITEM :Z :AA "0 SETITEM :Z :BB "0 ]]
PR [END]
END</langsyntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function Is_self_describing( n )
local s = tostring( n )
 
Line 1,626 ⟶ 1,849:
for i = 1, 999999999 do
print( Is_self_describing( i ) )
end</langsyntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">isSelfDescribing[n_Integer] := (RotateRight[DigitCount[n]] == PadRight[IntegerDigits[n], 10])</langsyntaxhighlight>
<pre>Select[Range[10^10 - 1], isSelfDescribing]
-> {1210,2020,21200,3211000,42101000,521001000,6210001000}</pre>
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight Matlablang="matlab">function z = isSelfDescribing(n)
s = int2str(n)-'0'; % convert to vector of digits
y = hist(s,0:9);
z = all(y(1:length(s))==s);
end;</langsyntaxhighlight>
 
Test function:
 
<langsyntaxhighlight Matlablang="matlab">for k = 1:1e10,
if isSelfDescribing(k),
printf('%i\n',k);
end
end; </langsyntaxhighlight>
 
Output:
Line 1,655 ⟶ 1,878:
 
=={{header|MiniScript}}==
<langsyntaxhighlight MiniScriptlang="miniscript">numbers = [12, 1210, 1300, 2020, 21200, 5]
occurrences = function(test, values)
Line 1,680 ⟶ 1,903:
end if
end for
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,694 ⟶ 1,917:
{{trans|Pascal}}
{{works with|ADW Modula-2|any (Compile with the linker option ''Console Application'').}}
<langsyntaxhighlight lang="modula2">
MODULE SelfDescribingNumber;
 
Line 1,746 ⟶ 1,969:
WriteLn;
END SelfDescribingNumber.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,761 ⟶ 1,984:
This is a brute-force algorithm. To speed-up, it uses integers instead of strings and the variable “digits” is allocated once, placed in global scope and accessed directly by the two functions (something I generally avoid). We have been able to check until 1_000_000_000.
 
<langsyntaxhighlight lang="nim">import algorithm, sequtils, std/monotimes, times
 
type Digit = 0..9
Line 1,787 ⟶ 2,010:
echo n, " in ", getMonoTime() - t0
 
echo "\nTotal time: ", getMonoTime() - t0</langsyntaxhighlight>
 
{{out}}
Line 1,800 ⟶ 2,023:
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
-- REXX program to check if a number (base 10) is self-describing.
parse arg x y .
Line 1,817 ⟶ 2,040:
say number "is a self describing number"
end
</syntaxhighlight>
</lang>
'''output''' when using the input of: <tt> 0 999999999 </tt>
<pre style="overflow:scroll">
Line 1,831 ⟶ 2,054:
=={{header|PARI/GP}}==
This is a finite set...
<langsyntaxhighlight lang="parigp">S=[1210, 2020, 21200, 3211000, 42101000, 521001000, 6210001000];
isself(n)=vecsearch(S,n)</langsyntaxhighlight>
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">Program SelfDescribingNumber;
 
uses
Line 1,877 ⟶ 2,100:
writeln (' ', x);
writeln('Job done.');
end.</langsyntaxhighlight>
Output:
<pre>
Line 1,894 ⟶ 2,117:
 
The number is self-descriptive If the arrays are equal.
<langsyntaxhighlight lang="perl">sub is_selfdesc
{
local $_ = shift;
Line 1,905 ⟶ 2,128:
for (0 .. 100000, 3211000, 42101000) {
print "$_\n" if is_selfdesc($_);
}</langsyntaxhighlight>
Output:
<pre>1210
Line 1,915 ⟶ 2,138:
=={{header|Phix}}==
{{Trans|Ada}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function self_desc(integer i)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence digits = repeat(0,10), counts = repeat(0,10)
<span style="color: #008080;">function</span> <span style="color: #000000;">self_desc</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
integer n = 0, digit
<span style="color: #004080;">sequence</span> <span style="color: #000000;">digits</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;">10</span><span style="color: #0000FF;">),</span>
while 1 do
<span style="color: #000000;">counts</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;">10</span><span style="color: #0000FF;">)</span>
digit := mod(i,10)
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">digit</span>
digits[10-n] := digit
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
counts[digit+1] += 1
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
i = floor(i/10)
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">10</span><span style="color: #0000FF;">-</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">digit</span>
if i=0 then exit end if
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
n += 1
<span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end while
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
return digits[10-n..10] = counts[1..n+1]
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</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>
end function
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
atom t0 = time()
<span style="color: #008080;">return</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">10</span><span style="color: #0000FF;">-</span><span style="color: #000000;">n</span><span style="color: #0000FF;">..</span><span style="color: #000000;">10</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">counts</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: #000000;">1</span><span style="color: #0000FF;">]</span>
for i=10 to 100_000_000 by 10 do
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
if self_desc(i) then ?i end if
end for
<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>
printf(1,"done (%3.2fs)",time()-t0)</lang>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">10</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100_000_000</span> <span style="color: #008080;">by</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">self_desc</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: #0000FF;">?</span><span style="color: #000000;">i</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: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"done (%s)\n"</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>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,945 ⟶ 2,173:
===generator===
{{trans|Python}}
Not quite as fast as I hoped it would be, although a bazillion times faster than the above and a good five times faster than Python, the following self(20) completes in just over half a second whereas self(24) takes nearly 9s, and it continues getting exponentially slower after that. Curiously, it is the early stages (same output) that slow down, whereas the latter ones always complete fairly quickly.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>procedure impl(sequence d, c, integer m)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
if m>=0 then
<span style="color: #008080;">procedure</span> <span style="color: #000000;">impl</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
integer l = length(d)
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
if l and d == c[1..l] then
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</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>
string ds = ""
<span style="color: #008080;">if</span> <span style="color: #000000;">l</span> <span style="color: #008080;">and</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">l</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
for i=1 to l do
<span style="color: #004080;">string</span> <span style="color: #000000;">ds</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
integer ch = d[i]+'0'
<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: #000000;">l</span> <span style="color: #008080;">do</span>
if ch>'9' then ch += 'a'-'9'-1 end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</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: #008000;">'0'</span>
ds &= ch
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">+=</span> <span style="color: #008000;">'a'</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'9'</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #000000;">ds</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">ch</span>
printf(1,"%s\n",ds)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end if
<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;">"%s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span>
sequence dd = d&0
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=c[l+1] to m do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">dd</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">0</span>
dd[$] = i
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">to</span> <span style="color: #000000;">m</span> <span style="color: #008080;">do</span>
if i>l or c[i+1]!=dd[i+1] then
<span style="color: #000000;">dd</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
c[i+1] += 1
<span style="color: #004080;">integer</span> <span style="color: #000000;">i1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
impl(dd,c,m-i)
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">l</span> <span style="color: #008080;">or</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">dd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
c[i+1] -= 1
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #000000;">impl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dd</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #000000;">m</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
procedure self(integer n)
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
impl({}, repeat(0,n+1), n)
end procedure
<span style="color: #008080;">procedure</span> <span style="color: #000000;">self</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
self(20)</lang>
<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;">impl</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;">n</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: #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>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">self</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,993 ⟶ 2,227:
f210000000000001000
g2100000000000001000
"1.2s"
</pre>
===even faster===
Finishes in less than a tenth of a second
{{trans|Seed7}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant string aleph = tagset('9','0')&tagset('z','a')&tagset('Z','A')
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
-- ie "0123456789abc..zABC..Z" (62 characters)
<span style="color: #008080;">constant</span> <span style="color: #004080;">string</span> <span style="color: #000000;">aleph</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'9'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'z'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">)</span>
 
<span style="color: #000080;font-style:italic;">-- ie "0123456789abc..zABC..Z" (62 characters)</span>
procedure gen(integer n)
for ones=iff(n>=7?2:0) to min(2,n-3) do
sequence digits = repeat(0,n),
counts = repeat(0,n)
digits[1] := n-2-ones
if digits[1]<>2 then
digits[digits[1]+1] := 1
digits[2] := 2
digits[3] := 1
else
digits[2] := (ones<>0)
digits[3] := 2
end if
for i=1 to n do
counts[digits[i]+1] += 1
end for
if counts=digits then
string s = ""
for i=1 to n do
integer di = digits[i]
s &= aleph[di+1]
end for
printf(1,"%s\n",s)
end if
end for
end procedure
<span style="color: #008080;">procedure</span> <span style="color: #000000;">gen</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
for n=1 to length(aleph)+3 do
<span style="color: #008080;">for</span> <span style="color: #000000;">ones</span><span style="color: #0000FF;">=</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">7</span><span style="color: #0000FF;">?</span><span style="color: #000000;">2</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
gen(n)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">digits</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;">n</span><span style="color: #0000FF;">),</span>
end for</lang>
<span style="color: #000000;">counts</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;">n</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: #0000FF;">:=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">ones</span>
<span style="color: #008080;">if</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: #000000;">2</span> <span style="color: #008080;">then</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;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">1</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;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">2</span>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">:=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ones</span><span style="color: #0000FF;"><></span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</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: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">d11</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: #000000;">1</span>
<span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d11</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: #008080;">if</span> <span style="color: #000000;">counts</span><span style="color: #0000FF;">=</span><span style="color: #000000;">digits</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</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: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">di</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: #000000;">s</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">aleph</span><span style="color: #0000FF;">[</span><span style="color: #000000;">di</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</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;">"%s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</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: #008080;">end</span> <span style="color: #008080;">procedure</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: #008080;">for</span> <span style="color: #000000;">n</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;">aleph</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">3</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">gen</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</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>
<!--</syntaxhighlight>-->
{{out}}
as above plus
Line 2,040 ⟶ 2,281:
...
Z2100000000000000000000000000000000000000000000000000000000001000
"0.0s"
</pre>
 
Line 2,045 ⟶ 2,287:
Works with: PHP 5.
 
<langsyntaxhighlight PHPlang="php"><?php
 
function is_describing($number) {
Line 2,062 ⟶ 2,304:
}
 
?></langsyntaxhighlight>
 
Output:
Line 2,070 ⟶ 2,312:
3211000
42101000</pre>
 
=={{header|Picat}}==
Here are three approaches. The latter two use a constraint modelling approach (a variant to the classic '''magic sequence''' problem, see below).
 
===Loop based approach===
<syntaxhighlight lang="picat">self_desc(Num,L) =>
L = [ I.to_integer() : I in Num.to_string()],
Len = L.len,
if sum(L) != Len then fail end,
foreach(J in L)
% cannot be a digit larger than the length of Num
if J >= Len then fail end
end,
foreach(I in 0..Len-1)
if sum([1 : J in L, I==J]) != L[I+1] then
fail
end
end.</syntaxhighlight>
 
===Constraint model 1===
Check if a number N is a self-describing number
<syntaxhighlight lang="picat">self_desc_cp(Num, Sequence) =>
N = length(Num.to_string()),
 
Sequence = new_list(N),
Sequence :: 0..N-1,
 
foreach(I in 0..N-1) count(I,Sequence,#=,Sequence[I+1]) end,
N #= sum(Sequence),
to_num(Sequence,10,Num),
scalar_product({ I : I in 0..N-1}, Sequence, N),
 
solve([ffd,updown], Sequence).</syntaxhighlight>
 
===Constraint model 2===
Same idea as <code>self_desc_cp/2</code> but a different usage: generate all solutions of a specific length Len.
<syntaxhighlight lang="picat">self_desc_cp_len(Len, Num) =>
 
Sequence = new_list(Len),
Sequence :: 0..Len-1,
 
Len #= sum(Sequence),
scalar_product({ I : I in 0..Len-1}, Sequence, Len),
to_num(Sequence,10,Num),
foreach(I in 0..Len-1) count(I,Sequence,#=,Sequence[I+1]) end,
 
solve([ffc,inout], Sequence).
 
%
% Converts a number Num to/from a list of integer List given a base Base
%
to_num(List, Base, Num) =>
Len = length(List),
Num #= sum([List[I]*Base**(Len-I) : I in 1..Len]).</syntaxhighlight>
 
===Testing===
Testing some numbers using <code>self_desc_cp/2</code>:
<syntaxhighlight lang="picat">go =>
List = [1210, 2020, 21200, 3211000, 42101000,
123456,98,10,-121,0,1,
9210000001000],
foreach(N in List)
printf("%w: %w\n", N, cond(self_desc_cp(N,_S),"self desc", "not self desc"))
end,
nl.</syntaxhighlight>
 
{{out}}
<pre>2020: self desc
21200: self desc
3211000: self desc
42101000: self desc
123456: not self desc
98: not self desc
10: not self desc
-121: not self desc
0: not self desc
1: not self desc
9210000001000: self desc
</pre>
 
===Generate all solutions of a specific length===
Using <code>self_desc_cp_len/3</code> to generates all solutions of length 1..13:
<syntaxhighlight lang="picat">go2 =>
Len :: 1..13,
println(findall(Num, (indomain(Len), self_desc_cp_len(Len,Num)))),
nl.
</syntaxhighlight>
 
{{out}}
<pre>[1210,2020,21200,3211000,42101000,521001000,6210001000,72100001000,821000001000,9210000001000]</pre>
 
===Magic sequence===
The two constraint modelling approaches are variations of the classic '''magic sequence''' problem:
 
''A magic sequence of length n is a sequence of integers x0 . . xn-1 between
0 and n-1, such that for all i in 0 to n-1, the number i occurs exactly xi
times in the sequence. For instance, 6,2,1,0,0,0,1,0,0,0 is a magic sequence
since 0 occurs 6 times in it, 1 occurs twice.''
 
Here is one way to model this magic sequence problem.
<syntaxhighlight lang="picat">go3 ?=>
member(N, 4..1000),
magic_sequenceN,Seq),
println(N=Seq),
fail,
nl.
go3 => true.
 
magic_sequence(N, Sequence) =>
Sequence = new_list(N),
Sequence :: 0..N-1,
foreach(I in 0..N-1)
Sequence[I+1] #= sum([Sequence[J] #= I : J in 1..N])
end,
sum(Sequence) #= N,
sum([I*Sequence[I+1] : I in 0..N-1]) #= N,
solve([ff,split], Sequence).</syntaxhighlight>
 
{{out}}
<pre>4 = [1,2,1,0]
4 = [2,0,2,0]
5 = [2,1,2,0,0]
7 = [3,2,1,1,0,0,0]
8 = [4,2,1,0,1,0,0,0]
9 = [5,2,1,0,0,1,0,0,0]
10 = [6,2,1,0,0,0,1,0,0,0]
11 = [7,2,1,0,0,0,0,1,0,0,0]
12 = [8,2,1,0,0,0,0,0,1,0,0,0]
13 = [9,2,1,0,0,0,0,0,0,1,0,0,0]
14 = [10,2,1,0,0,0,0,0,0,0,1,0,0,0]
15 = [11,2,1,0,0,0,0,0,0,0,0,1,0,0,0]
16 = [12,2,1,0,0,0,0,0,0,0,0,0,1,0,0,0]
17 = [13,2,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
18 = [14,2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
19 = [15,2,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
20 = [16,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
21 = [17,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
22 = [18,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
23 = [19,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
24 = [20,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
25 = [21,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
26 = [22,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
27 = [23,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
28 = [24,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
29 = [25,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
30 = [26,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
31 = [27,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0]
32 = [28,2,1,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,1,0,0,0]
33 = [29,2,1,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,1,0,0,0]
34 = [30,2,1,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,1,0,0,0]
35 = [31,2,1,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,1,0,0,0]
36 = [32,2,1,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,1,0,0,0]
37 = [33,2,1,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,1,0,0,0]
38 = [34,2,1,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,1,0,0,0]
39 = [35,2,1,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,1,0,0,0]
40 = [36,2,1,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,1,0,0,0]
...</pre>
 
===Algorithmic approach===
Except for the self describing number 2020, these sequences can be found by the following "algorithmic" approach:
<syntaxhighlight lang="picat">magic_sequence_alg(N, Sequence) =>
Sequence = new_list(N,0),
Sequence[1] := N - 4,
Sequence[2] := 2,
Sequence[3] := 1,
Sequence[N-3] := 1.</syntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de selfDescribing (N)
(fully '((D I) (= D (cnt = N (circ I))))
(setq N (mapcar format (chop N)))
(range 0 (length N)) ) )</langsyntaxhighlight>
Output:
<pre>: (filter selfDescribing (range 1 4000000))
Line 2,083 ⟶ 2,492:
According to the Wiki definition, the sum of the products of the index and the
digit contained at the index should equal the number of digits in the number:
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Test-SelfDescribing ([int]$Number)
{
Line 2,096 ⟶ 2,505:
$sum -eq $digits.Count
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
Test-SelfDescribing -Number 2020
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,105 ⟶ 2,514:
</pre>
It takes a very long while to test 100,000,000 numbers, and since they are already known just test a few:
<syntaxhighlight lang="powershell">
<lang PowerShell>
11,2020,21200,321100 | ForEach-Object {
[PSCustomObject]@{
Line 2,112 ⟶ 2,521:
}
} | Format-Table -AutoSize
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,125 ⟶ 2,534:
=={{header|Prolog}}==
Works with SWI-Prolog and library clpfd written by <b>Markus Triska</b>.
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(clpfd)).
 
self_describling :-
Line 2,231 ⟶ 2,640:
 
run(Var,[Other|RRest], [1, Var],[Other|RRest]):-
dif(Var,Other).</langsyntaxhighlight>
 
Output
Line 2,249 ⟶ 2,658:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">Procedure isSelfDescribing(x.q)
;returns 1 if number is self-describing, otherwise it returns 0
Protected digitCount, digit, i, digitSum
Line 2,321 ⟶ 2,730:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Sample output:
<pre>1210 is selfdescribing.
Line 2,376 ⟶ 2,785:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">>>> def isSelfDescribing(n):
s = str(n)
return all(s.count(str(i)) == int(ch) for i, ch in enumerate(s))
Line 2,383 ⟶ 2,792:
[1210, 2020, 21200, 3211000]
>>> [(x, isSelfDescribing(x)) for x in (1210, 2020, 21200, 3211000, 42101000, 521001000, 6210001000)]
[(1210, True), (2020, True), (21200, True), (3211000, True), (42101000, True), (521001000, True), (6210001000, True)]</langsyntaxhighlight>
===Generator===
From [http://leetm.mingpao.com/cfm/Forum3.cfm?CategoryID=1&TopicID=1545&TopicOrder=Desc&TopicPage=1 here].
<langsyntaxhighlight lang="python">def impl(d, c, m):
if m < 0: return
if d == c[:len(d)]: print d
Line 2,396 ⟶ 2,805:
def self(n): impl([], [0]*(n+1), n)
self(10)</langsyntaxhighlight>
Output:
<pre>[]
Line 2,409 ⟶ 2,818:
=={{header|Quackery}}==
 
<langsyntaxhighlight Quackerylang="quackery"> [ tuck over peek
1+ unrot poke ] is item++ ( n [ --> [ )
 
Line 2,430 ⟶ 2,839:
4000000 times
[ i^ self-desc if
[ i^ echo cr ] ]</langsyntaxhighlight>
 
{{out}}
Line 2,441 ⟶ 2,850:
 
=={{header|Racket}}==
<langsyntaxhighlight Racketlang="racket">#lang racket
(define (get-digits number (lst null))
(if (zero? number)
Line 2,454 ⟶ 2,863:
(and bool
(= (count (lambda (x) (= x i)) digits)
(list-ref digits i)))))))</langsyntaxhighlight>
 
Sadly, the implementation is too slow for the optional task, taking somewhere around 3 minutes to check all numbers below 100.000.000
Line 2,460 ⟶ 2,869:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>my @values = <1210 2020 21200 3211000
42101000 521001000 6210001000 27 115508>;
 
Line 2,480 ⟶ 2,889:
}
 
.say if .&sdn for ^9999999;</langsyntaxhighlight>
Output:
<pre>
Line 2,499 ⟶ 2,908:
 
=={{header|Red}}==
<langsyntaxhighlight Redlang="red">Red []
 
;;-------------------------------------
Line 2,529 ⟶ 2,938:
 
repeat i 4000000 [ if isSDN? to-string i [print i] ]
</syntaxhighlight>
</lang>
'''output'''
<pre>1210
Line 2,542 ⟶ 2,951:
&nbsp; and &nbsp; [http://oeis.org/A138480 OEIS A138480].
===digit by digit test===
<langsyntaxhighlight lang="rexx">/*REXX program determines if a number (in base 10) is a self─describing, */
/*────────────────────────────────────────────────────── self─descriptive, */
/*────────────────────────────────────────────────────── autobiographical, or a */
Line 2,567 ⟶ 2,976:
if substr(?,j,1)\==L-length(space(translate(?,,j-1),0)) then return 1
end /*j*/
return 0 /*faster if used inverted truth table. */</langsyntaxhighlight>
<pre>
╔══════════════════════════════════════════════════════════════════╗
Line 2,590 ⟶ 2,999:
===faster method===
(Uses table lookup.)
<langsyntaxhighlight lang="rexx">/*REXX program determines if a number (in base 10) is a self-describing number.*/
parse arg x y . /*obtain optional arguments from the CL*/
if x=='' | x=="," then exit /*Not specified? Then get out of Dodge*/
Line 2,608 ⟶ 3,017:
say right(n,w) 'is a self-describing number.'
end /*n*/
/*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''output''' &nbsp; is the same as the 1<sup>st</sup> REXX example.
 
Line 2,615 ⟶ 3,024:
 
(Results are instantaneous.)
<langsyntaxhighlight lang="rexx">/*REXX program determines if a number (in base 10) is a self-describing number.*/
parse arg x y . /*obtain optional arguments from the CL*/
if x=='' | x=="," then exit /*Not specified? Then get out of Dodge*/
Line 2,631 ⟶ 3,040:
if _<x | _>y then iterate /*if not self-describing, try again. */
say right(_, w) 'is a self-describing number.'
end /*n*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''output''' &nbsp; is the same as the 1<sup>st</sup> REXX example.
<br><br>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Self-describing numbers
 
Line 2,661 ⟶ 3,070:
end
return sum
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,670 ⟶ 3,079:
42101000
</pre>
 
=={{header|RPL}}==
With some reasoning, one can find that digits must be between 0 and 4: just try manually to make a SDN with a 5 or greater and you will see it's impossible. The task enumerator takes this into account by counting in base 5, skipping numbers whose digital root is not equal to the number of digits and adding a final zero. Brute force is 30 times slower.
{{works with|HP|49}}
≪ STR→ { }
1 PICK3 SIZE '''FOR''' j
OVER j DUP SUB STR→ + '''NEXT'''
1 SF
0 ROT SIZE 1 - '''FOR''' j
DUP j 1 + GET
'''IF''' OVER 1 ≪ j == ≫ DOLIST ∑LIST ≠ '''THEN'''
1 CF DUP SIZE 'j' STO '''END'''
'''NEXT''' NIP
1 FS?
≫ '<span style="color:blue">SELF?</span>' STO
≪ →STR
1 OVER SIZE 1 - SUB <span style="color:grey">@ remove final zero</span>
0
1 PICK 3 SIZE '''FOR''' j
5 * OVER j DUP SUB STR→ + '''NEXT''' <span style="color:grey">@ convert from base 5</span>
NIP DUP
'''DO'''
DROP 1 + DUP ""
'''DO''' SWAP 5 IDIV2 ROT + <span style="color:grey">@ convert to base 5</span>
'''UNTIL''' OVER NOT '''END'''
NIP STR→
'''UNTIL''' DUP 1 - 9 MOD OVER XPON 1 + == '''END''' <span style="color:grey">@ check digital root</span>
NIP 10 * <span style="color:grey">@ add final zero</span>
≫ '<span style="color:blue">NEXTCAND</span>' STO
≪ → max
≪ { } 10
'''WHILE''' DUP max < '''REPEAT'''
'''IF''' DUP <span style="color:blue">SELF?</span> '''THEN''' SWAP OVER + SWAP '''END'''
<span style="color:blue">NEXTCAND</span>
'''END''' DROP
≫ ≫ '<span style="color:blue">TASK</span>' STO
 
9999 <span style="color:blue">TASK</span>
{{out}}
<pre>
1: {1210 2020}
</pre>
Runs in 43 seconds on a HP-48G.
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def self_describing?(n)
digits = n.digits.reverse
digits.each_with_index.all?{|digit, idx| digits.count(idx) == digit}
end
 
3_300_000.times {|n| puts n if self_describing?(n)}</langsyntaxhighlight>
outputs
<pre>1210
Line 2,685 ⟶ 3,139:
 
{{trans|Wren}}
<langsyntaxhighlight lang="ruby">def selfDesc(n)
ns = n.to_s
nc = ns.size
Line 2,734 ⟶ 3,188:
end
osecs = (Time.now - start)
print("\nTook #{osecs} secs overall")</langsyntaxhighlight>
 
System: I7-6700HQ, 3.5 GHz, Linux Kernel 5.6.17, Ruby 2.7.1
Line 2,776 ⟶ 3,230:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight Runbasiclang="runbasic">for i = 0 to 50000000 step 10
a$ = str$(i)
for c = 1 TO len(a$)
Line 2,792 ⟶ 3,246:
next i
print "== End =="
end</langsyntaxhighlight>
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">
fn is_self_desc(xx: u64) -> bool
{
Line 2,818 ⟶ 3,272:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
===Functional Programming===
<langsyntaxhighlight Scalalang="scala">object SelfDescribingNumbers extends App {
def isSelfDescribing(a: Int): Boolean = {
val s = Integer.toString(a)
Line 2,835 ⟶ 3,289:
 
println("Successfully completed without errors.")
}</langsyntaxhighlight>
 
See it running in your browser by [https://scastie.scala-lang.org/vQv61PpoSLeWwyVipLUevQ Scastie (JVM)].
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed">$ include "seed7_05.s7i";
 
const func boolean: selfDescr (in string: stri) is func
Line 2,905 ⟶ 3,359:
gen(number);
end for;
end func;</langsyntaxhighlight>
 
Output:
Line 2,928 ⟶ 3,382:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func sdn(Number n) {
var b = [0]*n.len
var a = n.digits.flip
Line 2,943 ⟶ 3,397:
 
say "\nSelf-descriptive numbers less than 1e5 (in base 10):"
^1e5 -> each { |i| say i if sdn(i) }</langsyntaxhighlight>
{{out}}
<pre>
Line 2,963 ⟶ 3,417:
 
'''Extra credit:''' this will generate all the self-describing numbers in bases 7 to 36:
<langsyntaxhighlight lang="ruby">for b in (7 .. 36) {
var n = ((b-4) * b**(b-1) + 2*(b**(b-2)) + b**(b-3) + b**3 -> base(b))
say "base #{'%2d' % b}: #{n}"
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,003 ⟶ 3,457:
=={{header|Swift}}==
 
<langsyntaxhighlight lang="swift">import Foundation
 
extension BinaryInteger {
Line 3,035 ⟶ 3,489:
}
 
dispatchMain()</langsyntaxhighlight>
 
{{out}}
Line 3,047 ⟶ 3,501:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
proc isSelfDescribing num {
set digits [split $num ""]
Line 3,062 ⟶ 3,516:
for {set i 0} {$i < 100000000} {incr i} {
if {[isSelfDescribing $i]} {puts $i}
}</langsyntaxhighlight>
 
=={{header|UNIX Shell}}==
{{works with|bash}}
Seeking self-describing numbers up to 100,000,000 is very time consuming, so we'll just verify a few numbers.
<langsyntaxhighlight lang="bash">selfdescribing() {
local n=$1
local count=()
Line 3,086 ⟶ 3,540:
printf "%d\t%s\n" $n no
fi
done</langsyntaxhighlight>
{{output}}
<pre>0 no
Line 3,101 ⟶ 3,555:
Takes a very, very long time to check 100M numbers that I have to terminate the script. But the function
works.
<syntaxhighlight lang="vb">
<lang vb>
Function IsSelfDescribing(n)
IsSelfDescribing = False
Line 3,141 ⟶ 3,595:
end_time = Now
WScript.StdOut.WriteLine "Elapse Time: " & DateDiff("s",start_time,end_time) & " seconds"
</syntaxhighlight>
</lang>
 
=={{header|Wren}}==
Heavily optimized to complete the search in a reasonable time for a scripting language.
<langsyntaxhighlight ecmascriptlang="wren">var selfDesc = Fn.new { |n|
var ns = "%(n)"
var nc = ns.count
Line 3,194 ⟶ 3,648:
}
var osecs = ((System.clock - start) * 10).round / 10
System.print("\nTook %(osecs) secs overall")</langsyntaxhighlight>
 
{{out}}
Line 3,212 ⟶ 3,666:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code ChOut=8, IntOut=11;
 
func SelfDesc(N); \Returns 'true' if N is self-describing
Line 3,246 ⟶ 3,700:
int N;
for N:= 0 to 100_000_000-1 do
if SelfDesc(N) then [IntOut(0, N); ChOut(0, ^ )]</langsyntaxhighlight>
 
Output:
Line 3,255 ⟶ 3,709:
=={{header|Yabasic}}==
{{trans|BBC_BASIC}}
<langsyntaxhighlight Yabasiclang="yabasic">FOR N = 1 TO 5E7
IF FNselfdescribing(N) PRINT N
NEXT
Line 3,274 ⟶ 3,728:
FOR I = 0 TO 8 : L = L + D(I) : NEXT
RETURN O = L
END SUB</langsyntaxhighlight>
 
=={{header|Zig}}==
{{works with|Zig|0.11.0dev}}
<syntaxhighlight lang="zig">const std = @import("std");</syntaxhighlight>
<syntaxhighlight lang="zig">// Return true if number is self describing
fn isSelfDescribing(number: u32) bool {
var n = number; // Zig parameters are immutable, copy to var.
 
// 10 is the maximum number of decimal digits in a 32-bit integer.
var array: [10]u32 = undefined;
 
// Add digits to array.
var i: u32 = 0;
while (n != 0 or i == 0) : (n /= 10) {
array[i] = n % 10;
i += 1;
}
var digits = array[0..i]; // Slice to give just the digits added.
std.mem.reverse(u32, digits);
 
// Check digits. Brute force.
for (digits, 0..) |predicted_count, predicted_digit| {
var count: u8 = 0;
for (digits) |digit| {
if (digit == predicted_digit) count += 1;
}
if (count != predicted_count) return false;
}
return true;
}</syntaxhighlight>
<syntaxhighlight lang="zig">pub fn main() anyerror!void {
const stdout = std.io.getStdOut().writer();
 
for (0..100_000_000) |number| {
if (isSelfDescribing(@intCast(number)))
try stdout.print("{}\n", .{number});
}
}</syntaxhighlight>
{{out}}
<pre>1210
2020
21200
3211000
42101000</pre>
===Alternative With "Optimizations"===
Here is an alternative implementation of <em>isSelfDescribing()</em> that
illustrates additional computationally cheap ways of partially eliminating
integers that are not self describing. These ideas were filched from other
solutions on this page (primarily Wren & PowerShell). The code works.
Refactoring for speed is a further exercise.
 
<syntaxhighlight lang="zig">/// Return true if number is self describing
fn isSelfDescribing(number: u32) bool {
// Get the digits (limit scope of variables in a Zig block expression)
// 1234 -> { 1, 2, 3, 4}
const digits = blk: {
var n = number; // Zig parameters are immutable, copy to var.
// 10 is the maximum number of decimal digits in a 32-bit integer.
var array: [10]u32 = undefined;
 
// Add base 10 digits to array.
var i: u32 = 0;
while (n != 0 or i == 0) : (n /= 10) {
array[i] = n % 10;
i += 1;
}
var slice = array[0..i]; // Slice to give only the digits added.
std.mem.reverse(u32, slice);
break :blk slice;
};
{
// wikipedia: last digit must be zero
if (digits[digits.len - 1] != 0) return false;
}
{
// cannot have a digit >= number of digits
for (digits) |n| if (n >= digits.len) return false;
}
{
// sum of digits must equal number of digits
var sum: u32 = 0;
for (digits) |n| sum += n; // > digits.len short-circuit ?
if (sum != digits.len) return false;
}
{
// sum of the products of the index and the digit contained at the index
// should equal the number of digits in the number
var sum: u32 = 0;
for (digits, 0..) |n, index| sum += n * @as(u32, @truncate(index));
if (sum != digits.len) return false;
}
// Final elimination. 100% effective. Brute force.
{
// Self describing check of digits.
for (digits, 0..) |expected_count, expected_digit| {
var count: u8 = 0;
for (digits) |digit| {
if (digit == expected_digit) count += 1;
}
if (count != expected_count) return false;
}
}
return true;
}</syntaxhighlight>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn isSelfDescribing(n){
if (n.bitAnd(1)) return(False); // Wikipedia: last digit must be zero
nu:= n.toString();
ns:=["0".."9"].pump(String,nu.inCommon,"len"); //"12233".inCommon("2")-->"22"
(nu+"0000000000")[0,10] == ns; //"2020","2020000000"
}</langsyntaxhighlight>
Since testing a humongous number of numbers is slow, chunk the task into a bunch of threads. Even so, it pegged my 8 way Ivy Bridge Linux box for quite some time (eg the Python & AWK solutions crush this one).
<langsyntaxhighlight lang="zkl">//[1..0x4_000_000].filter(isSelfDescribing).println();
const N=0d500_000;
[1..0d100_000_000, N] // chunk and thread, 200 in this case
.apply(fcn(n){ n.filter(N,isSelfDescribing) }.future)
.filter().apply("noop").println();</langsyntaxhighlight>
A future is a thread returning a [delayed] result, future.filter/future.noop will block until the future coughs up the result. Since the results are really sparse for the bigger numbers, filter out the empty results.
{{out}}
9,476

edits