Lychrel numbers: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(29 intermediate revisions by 14 users not shown)
Line 72:
*   [http://mathoverflow.net/questions/117104/status-of-the-196-conjecture/117277#117277 Status of the 196 conjecture?] Mathoverflow.
<br><br>
 
=={{header|11l}}==
{{trans|D}}
 
<syntaxhighlight lang="11l">F rev(n)
R BigInt(reversed(String(n)))
 
[BigInt = (Bool, BigInt)] cache
 
F lychrel(BigInt =n)
I n C :cache
R :cache[n]
 
V r = rev(n)
V res = (1B, n)
[BigInt] seen
L(i) 1000
n += r
r = rev(n)
I n == r
res = (0B, BigInt(0))
L.break
I n C :cache
res = :cache[n]
L.break
seen [+]= n
 
L(x) seen
:cache[x] = res
R res
 
[Int] seeds, related, palin
 
L(i) 1..9999
V tf_s = lychrel(i)
I !tf_s[0]
L.continue
I BigInt(i) == tf_s[1]
seeds [+]= i
E
related [+]= i
I BigInt(i) == rev(i)
palin [+]= i
 
print(seeds.len‘ Lychrel seeds: ’seeds)
print(related.len‘ Lychrel related’)
print(palin.len‘ Lychrel palindromes: ’palin)</syntaxhighlight>
 
{{out}}
<pre>
5 Lychrel seeds: [196, 879, 1997, 7059, 9999]
244 Lychrel related
3 Lychrel palindromes: [4994, 8778, 9999]
</pre>
 
=={{header|ALGOL 68}}==
Line 77 ⟶ 131:
<br>
Uses the associative array from the Associative array iteration task.
<langsyntaxhighlight lang="algol68">PR read "aArray.a68" PR
 
# number of additions to attempt before deciding the number is Lychrel #
Line 244 ⟶ 298:
OD;
print( ( newline ) )
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 251 ⟶ 305:
There are 3 palindromic Lychrel numbers up to 10000: 4994 8778 9999
</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">on Lychrels(numberLimit, iterationLimit)
script o
property digits : missing value -- Digits of the current startNumber or a derived sum.
property stigid : missing value -- Reverse thereof.
property digitLists : missing value -- Copies of the digit lists in the current sequence.
-- The digit lists from earlier Lychrel sequences, grouped into 1000 sublists
-- indexed by their last three digits (+ 1) to speed up searches for them.
property earlierDigitLists : listOfLists(1000)
property subgroup : missing value -- Sublist picked from earlierDigitLists.
-- Lychrel output.
property seeds : {}
property relateds : {}
property palindromics : {}
-- Subhandler: Has the current list of digits come up in the sequence for an earlier Lychrel?
on isRelated()
-- Unless it only has one digit, look for it in the appropriate subgroup of earlierDigitLists.
set digitCount to (count my digits)
if (digitCount > 1) then
set i to (item -2 of my digits) * 10 + (end of my digits) + 1
if (digitCount > 2) then set i to i + (item -3 of my digits) * 100
set subgroup to item i of my earlierDigitLists
-- It's faster to test this using a repeat than with 'is in'!
repeat with i from 1 to (count my subgroup)
if (item i of my subgroup = digits) then return true
end repeat
end if
return false
end isRelated
end script
repeat with startNumber from 1 to numberLimit
-- Get the number's digits and their reverse.
set o's digits to {}
set temp to startNumber
repeat until (temp = 0)
set beginning of o's digits to temp mod 10
set temp to temp div 10
end repeat
set o's stigid to reverse of o's digits
-- Note if the number itself is palindromic.
set startNumberIsPalindrome to (o's digits = o's stigid)
if (o's isRelated()) then
-- It(s digits) occurred in the sequence for an earlier Lychrel, so it's a related Lychrel.
set end of o's relateds to startNumber
else
-- Otherwise run its sequence.
set o's digitLists to {}
set digitCount to (count o's digits)
-- Sequence loop.
repeat iterationLimit times
-- Add the reversed digits to those of the current number.
set carry to 0
repeat with i from digitCount to 1 by -1
set d to (item i of o's digits) + (item i of o's stigid) + carry
set item i of o's digits to d mod 10
set carry to d div 10
end repeat
if (carry > 0) then
set beginning of o's digits to carry
set digitCount to digitCount + 1
end if
-- If the sum's digits are palindromic, the start number's not a Lychrel.
set o's stigid to reverse of o's digits
set sumIsPalindrome to (o's digits = o's stigid)
if (sumIsPalindrome) then exit repeat
-- Otherwise, if the digits occurred in an earlier Lychrel sequence, the start number's a related Lychrel.
set startNumberIsRelated to (o's isRelated())
if (startNumberIsRelated) then
set sumIsPalindrome to false
exit repeat
end if
-- Otherwise keep a copy of the digits and go for the next number in the sequence.
copy o's digits to end of o's digitLists
end repeat
if (not sumIsPalindrome) then
-- No palindrome other than the start number occurred in the sequence,
-- so the number's a Lychrel. Store it as the relevant type.
if (startNumberIsRelated) then
set end of o's relateds to startNumber
else
set end of o's seeds to startNumber
end if
if (startNumberIsPalindrome) then set end of o's palindromics to startNumber
-- Store this sequence's digit lists based on their last three digits. There won't be any
-- single-digit lists (they're palindromes), but there may be some with only two digits.
repeat with thisList in o's digitLists
set i to (item -2 of thisList) * 10 + (end of thisList) + 1
set digitCount to (count thisList)
if (digitCount > 2) then set i to i + (item -3 of thisList) * 100
set end of item i of o's earlierDigitLists to thisList's contents
end repeat
end if
end if
end repeat
return {seeds:o's seeds, relateds:o's relateds, palindromics:o's palindromics}
end Lychrels
 
on listOfLists(len)
script o
property lst : {}
end script
repeat len times
set end of o's lst to {}
end repeat
return o's lst
end listOfLists
 
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
 
on task()
set numberLimit to 10000
set iterationLimit to 500
set {seeds:seeds, relateds:relateds, palindromics:palindromics} to Lychrels(numberLimit, iterationLimit)
set output to {"Lychrel numbers between 1 and " & numberLimit & ":", ""}
set end of output to ((count seeds) as text) & " seed Lychrels: " & join(seeds, ", ")
set end of output to ((count relateds) as text) & " related Lychrels"
set end of output to ((count palindromics) as text) & " palindromic Lychrels: " & join(palindromics, ", ")
return join(output, linefeed)
end task
 
task()</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"Lychrel numbers between 1 and 10000:
 
5 seed Lychrels: 196, 879, 1997, 7059, 9999
244 related Lychrels
3 palindromic Lychrels: 4994, 8778, 9999"</syntaxhighlight>
 
=={{header|BASIC}}==
Line 261 ⟶ 457:
 
I highly recommend to run this code in QB64. If this code is run in the other related versions, it can take about 20 minutes to run. In QB64 it only takes just seconds (11 seconds in my computer). This code has been tested to calculate up to 15000 numbers. BASIC doesn't have a way to manage such large numbers, but I implemented a way to do the sum through strings (an easy way to create a kind of array).
<langsyntaxhighlight lang="qbasic">
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' Lychrel Numbers V1.0 '
Line 587 ⟶ 783:
 
END FUNCTION
</syntaxhighlight>
</lang>
 
Output while running:
Line 618 ⟶ 814:
=={{header|C++}}==
{{trans|D}}
{{libheader|BoostGMP}}
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <map>
#include <vector>
#include <boost/multiprecision/cpp_intgmpxx.hpph>
 
using integer = mpz_class;
typedef boost::multiprecision::cpp_int integer;
 
integer reverse(integer n) {
{
integer rev = 0;
while (n > 0) {
{
rev = rev * 10 + (n % 10);
n /= 10;
Line 637 ⟶ 831:
}
 
void print_vector(const std::vector<integer>& vec) {
{
if (vec.empty())
return;
Line 648 ⟶ 841:
}
 
int main() {
{
std::map<integer, std::pair<bool, integer>> cache;
std::vector<integer> seeds, related, palindromes;
for (integer n = 1; n <= 10000; ++n) {
{
std::pair<bool, integer> p(true, n);
std::vector<integer> seen;
integer rev = reverse(n);
integer sum = n;
for (int i = 0; i < 500; ++i) {
{
sum += rev;
rev = reverse(sum);
if (rev == sum) {
{
p.first = false;
p.second = 0;
Line 669 ⟶ 858:
}
auto iter = cache.find(sum);
if (iter != cache.end()) {
{
p = iter->second;
break;
Line 694 ⟶ 882:
print_vector(palindromes);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 705 ⟶ 893:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="lisp">(ns lychrel.core
(require [clojure.string :as s])
(require [clojure.set :as set-op])
Line 780 ⟶ 968:
(println count-palindromes "Lychrel palindromes found:" palindrom-n))
)
</syntaxhighlight>
</lang>
 
{{out}}
Line 791 ⟶ 979:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun Lychrel (number &optional (max 500))
"Returns T if number is a candidate Lychrel (up to max iterations), and a second value with the sequence of sums"
(do* ((n number (+ n (parse-integer rev-str)))
Line 817 ⟶ 1,005:
Number of related found: ~D~%Palyndrome Lychrel numbers: ~D => ~a~%"
n max (length seeds) (nreverse (mapcar #'car seeds)) related (length palyndromes) (nreverse palyndromes)) ))
</syntaxhighlight>
</lang>
 
{{out}}
Line 828 ⟶ 1,016:
Palyndrome Lychrel numbers: 3 => (4994 8778 9999)
NIL
</pre>
 
=={{header|Crystal}}==
{{trans|Ruby}}
<syntaxhighlight lang="ruby">require "set"
require "big"
def add_reverse(num, max_iter=1000)
num = num.to_big_i
nums = [] of BigInt
(1..max_iter).each_with_object(Set.new([num])) do |_, nums|
num += reverse_int(num)
nums << num
return nums if palindrome?(num)
end
end
def palindrome?(num)
num == reverse_int(num)
end
def reverse_int(num)
num.to_s.reverse.to_big_i
end
def split_roots_from_relateds(roots_and_relateds)
roots = roots_and_relateds.dup
i = 1
while i < roots.size
this = roots[i]
if roots[0...i].any?{ |prev| this.intersects?(prev) }
roots.delete_at(i)
else
i += 1
end
end
root = roots.map{ |each_set| each_set.min }
related = roots_and_relateds.map{ |each_set| each_set.min }
related = related.reject{ |n| root.includes?(n) }
return root, related
end
def find_lychrel(maxn, max_reversions)
series = (1..maxn).map{ |n| add_reverse(n, max_reversions*2) }
roots_and_relateds = series.select{ |s| s.size > max_reversions }
split_roots_from_relateds(roots_and_relateds)
end
maxn, reversion_limit = 10000, 500
puts "Calculations using n = 1..#{maxn} and limiting each search to 2*#{reversion_limit} reverse-digits-and-adds"
lychrel, l_related = find_lychrel(maxn, reversion_limit)
puts " Number of Lychrel numbers: #{lychrel.size}"
puts " Lychrel numbers: #{lychrel}"
puts " Number of Lychrel related: #{l_related.size}"
pals = (lychrel + l_related).select{|x| palindrome?(x)}.sort
puts " Number of Lychrel palindromes: #{pals.size}"
puts " Lychrel palindromes: #{pals}"</syntaxhighlight>
 
{{out}}
<pre>
Calculations using n = 1..10000 and limiting each search to 2*500 reverse-digits-and-adds
Number of Lychrel numbers: 5
Lychrel numbers: [196, 879, 1997, 7059, 9999]
Number of Lychrel related: 244
Number of Lychrel palindromes: 3
Lychrel palindromes: [4994, 8778, 9999]
</pre>
 
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.conv, std.range, std.typecons, std.bigInt;
 
auto rev(in BigInt n) {
Line 882 ⟶ 1,136:
writeln(related.length, " Lychrel related");
writeln(palin.length, " Lychrel palindromes: ", palin);
}</langsyntaxhighlight>
{{out}}
<pre>5 Lychrel seeds: [196, 879, 1997, 7059, 9999]
Line 906 ⟶ 1,160:
The growth of the numbers was impressive, so a simple investigation: what of the growth per step for 196? The digit strings lengthened in a linear-looking way, so, what of a plot of step as x, vs Log10(n) as y? The result for 500 numbers went from step 0 and Log10(196) = 2·292256 to step 499 and 215·266386 and the linear correlation coefficient came out as 1·000 with y = 0·43328*x + 2·1616, which is to say that each advance increased the number by a factor of about 2·7. However, the plot (which alas, can't be posted here) does ''not'' show a random scatter about the straight line, it instead shows the points wobbling above and below the fitted line. A plot of the residuals shows the deviations coming in waves, but also cannot be posted here...
 
<syntaxhighlight lang="fortran">
<lang Fortran>
SUBROUTINE CROAK(GASP) !A dying message.
CHARACTER*(*) GASP !The message.
Line 1,298 ⟶ 1,552:
WRITE (6,*) "Unused STASH entries =",AVAILS(0)
END
</syntaxhighlight>
</lang>
 
Output: edited to put twenty numbers per line and omit the (1:''n'') of the output from BIGWRITE...
Line 1,335 ⟶ 1,589:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 13-09-2015
' compile with: fbc -s console
 
Line 1,428 ⟶ 1,682:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> Testing numbers: 1 to 10000
Line 1,440 ⟶ 1,694:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,570 ⟶ 1,824:
fmt.Println("Number of Lychrel palindromes:", len(pals))
fmt.Println(" Lychrel palindromes:", pals)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,582 ⟶ 1,836:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">module Main where
 
import Data.List
Line 1,631 ⟶ 1,885:
putStrLn $ show palindromicLychrel ++ " are palindromic Lychrel numbers."
putStrLn $ show lychrelSeeds ++ " are Lychrel seeds."
putStrLn $ "There are " ++ show relatedCount ++ " related Lychrel numbers."</langsyntaxhighlight>
{{Out}}
<pre>
Line 1,644 ⟶ 1,898:
Reverse digits:
 
<langsyntaxhighlight Jlang="j">revdig=:('x',~|.)&.":"0</langsyntaxhighlight>
 
Note that we need extended precision numbers because 500 iterations gets us into very large numbers even when we start small. For example, starting from 12:
 
<langsyntaxhighlight Jlang="j"> (+revdig)^:500(12)
989330226271793404132120335101444022368928728236373385750622261099268167362912850818170039990942038798808908830140199820181718948328173760873880172226156484473632718819962221534191534021132404387162721132989</langsyntaxhighlight>
 
Test whether a number is a lychrel (true or related) number within that 500 iteration limit:
 
<langsyntaxhighlight Jlang="j">lychrel500=: (~: revdig)@((+^:~: revdig)^:500)@(+revdig)"0</langsyntaxhighlight>
 
Number of these lychrel numbers not exceeding 10000 (we start from 0 here, because that's natural for J's primitives, so we need 10001 integers if we are to reach 10000):
 
<langsyntaxhighlight Jlang="j"> #L=:I.lychrel500 i.10001
249</langsyntaxhighlight>
 
(What are they? Note that this isn't a task requirement - just curiosity.)
 
<langsyntaxhighlight Jlang="j"> 3 83$L
196 295 394 493 592 689 691 788 790 879 887 978 986 1495 1497 1585 1587 1675 1677 1765 1767 1855 1857 1945 1947 1997 2494 2496 2584 2586 2674 2676 2764 2766 2854 2856 2944 2946 2996 3493 3495 3583 3585 3673 3675 3763 3765 3853 3855 3943 3945 3995 4079 4169 4259 4349 4439 4492 4494 4529 4582 4584 4619 4672 4674 4709 4762 4764 4799 4852 4854 4889 4942 4944 4979 4994 5078 5168 5258 5348 5438 5491 5493
5528 5581 5583 5618 5671 5673 5708 5761 5763 5798 5851 5853 5888 5941 5943 5978 5993 6077 6167 6257 6347 6437 6490 6492 6527 6580 6582 6617 6670 6672 6707 6760 6762 6797 6850 6852 6887 6940 6942 6977 6992 7059 7076 7149 7166 7239 7256 7329 7346 7419 7436 7491 7509 7526 7581 7599 7616 7671 7689 7706 7761 7779 7796 7851 7869 7886 7941 7959 7976 7991 8058 8075 8079 8089 8148 8165 8169 8179 8238 8255 8259 8269 8328
8345 8349 8359 8418 8435 8439 8449 8490 8508 8525 8529 8539 8580 8598 8615 8619 8629 8670 8688 8705 8709 8719 8760 8778 8795 8799 8809 8850 8868 8885 8889 8899 8940 8958 8975 8979 8989 8990 9057 9074 9078 9088 9147 9164 9168 9178 9237 9254 9258 9268 9327 9344 9348 9358 9417 9434 9438 9448 9507 9524 9528 9538 9597 9614 9618 9628 9687 9704 9708 9718 9777 9794 9798 9808 9867 9884 9888 9898 9957 9974 9978 9988 9999</langsyntaxhighlight>
 
To figure out which of these lychrel numbers were "true" lychrel numbers, we will need to work with sequences of sums seeded from these numbers. So let's just find those sequences:
 
<langsyntaxhighlight Jlang="j"> S=:(+revdig)^:(i.501)"0 L</langsyntaxhighlight>
 
And, let's take a peek at some of the numbers in these sequences (the first 10 values in each lychrel sequence, starting from the first lychrel candidate seeds):
 
<langsyntaxhighlight Jlang="j"> 10 10 {.S
196 887 1675 7436 13783 52514 94039 187088 1067869 10755470
295 887 1675 7436 13783 52514 94039 187088 1067869 10755470
Line 1,683 ⟶ 1,937:
788 1675 7436 13783 52514 94039 187088 1067869 10755470 18211171
790 887 1675 7436 13783 52514 94039 187088 1067869 10755470
879 1857 9438 17787 96558 182127 903408 1707717 8884788 17759676</langsyntaxhighlight>
 
So most of these are related... which ones are not? (An integer is owned if it is in the sequence for this lychrel candidate or for any previous candidates. A lychrel candidate is a true lychrel number if none of its sequence is owned by any previous candidate.)
 
<langsyntaxhighlight Jlang="j"> owned=: <@~.@,\S
#T=: (-. (<"1 S) +./@e.&> a:,}:owned)#L
5
T
196 879 1997 7059 9999</langsyntaxhighlight>
 
And, with that, we can find the count of "just related" lychrel numbers:
 
<langsyntaxhighlight Jlang="j"> L -&# T
244</langsyntaxhighlight>
 
And, finally, which of the (true or related) lychrel numbers were themselves palindromes?
 
<langsyntaxhighlight Jlang="j"> (#~(=revdig))L
4994 8778 9999</langsyntaxhighlight>
 
To reiterate, here's the collected definitions with the task required results (everything above this point was basically just documentation - J tends to need that kind of documentation, because of the nature of the language):
 
<langsyntaxhighlight Jlang="j"> revdig=:('x',~|.)&.":"0
lychrel500=: (~: revdig)@((+^:~: revdig)^:500)@(+revdig)"0
L=:I.lychrel500 i.10001
Line 1,717 ⟶ 1,971:
244
(#~(=revdig))L
4994 8778 9999</langsyntaxhighlight>
 
T is the "seed" or "true" lychrel numbers, and #T is how many of them we found. L is all of the candidates (both seeds and relateds), so the difference in the lengths of L and T is the number of related.
Line 1,724 ⟶ 1,978:
Translation of [[Lychrel_numbers#Python|Python]] via [[Lychrel_numbers#D|D]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.math.BigInteger;
import java.util.*;
 
Line 1,805 ⟶ 2,059:
System.out.printf("%d Lychrel palindromes: %s%n", palin.size(), palin);
}
}</langsyntaxhighlight>
 
<pre>5 Lychrel seeds: [196, 879, 1997, 7059, 9999]
Line 1,812 ⟶ 2,066:
 
=={{header|jq}}==
<langsyntaxhighlight lang="jq"># This workhorse function assumes its arguments are
# non-negative integers represented as decimal strings:
def add(num1;num2):
Line 1,875 ⟶ 2,129:
end
end ) ;
</syntaxhighlight>
</lang>
'''The task'''
<langsyntaxhighlight lang="jq">lychrel_dictionary(10001; 500)
| {seed, palindromic_seed, related: (.related | length) }</langsyntaxhighlight>
 
'''Output'''
Line 1,901 ⟶ 2,155:
{{works with|Julia|1.3}}
 
<langsyntaxhighlight lang="julia">const cache = Dict{BigInt, Tuple{Bool, BigInt}}()
 
Base.reverse(n::Integer) = parse(BigInt, string(n) |> reverse)
Line 1,954 ⟶ 2,208:
println(length(seeds), " lychrel seeds: ", join(seeds, ", "))
println(length(related), " lychrel related")
println(length(palin), " lychrel palindromes: ", join(palin, ", "))</langsyntaxhighlight>
 
{{out}}
Line 1,962 ⟶ 2,216:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.math.BigInteger
Line 2,023 ⟶ 2,277:
println("\nThere are ${palindromes.size} palindromic Lychrel numbers, namely")
println(palindromes)
}</langsyntaxhighlight>
 
{{out}}
Line 2,039 ⟶ 2,293:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
A few convenient functions:
<langsyntaxhighlight Mathematicalang="mathematica">palindromeQ[n_Integer] :=
Block[{digits = IntegerDigits[n]}, digits == Reverse@digits]
 
Line 2,049 ⟶ 2,303:
palindromeQ@
Catch[Nest[If[palindromeQ[#], Throw[#], nextNumber[#]] &,
nextNumber[n], 500]]</langsyntaxhighlight>
 
A list of all integers less 10,000 that do not evolve to a palindrome in 500 iterations
<langsyntaxhighlight Mathematicalang="mathematica">candidates = Cases[Range[10000], _?(lychrelQ@# &)];</langsyntaxhighlight>
The Lychrel seeds can be obtained from the list of candidates as follows:
<langsyntaxhighlight Mathematicalang="mathematica">seeds = {};
NestWhile[(seeds = {seeds, First@#};
test = NestList[nextNumber, First@#, 10];
Line 2,060 ⟶ 2,314:
Rest[#], _?(IntersectingQ[test,
NestList[nextNumber, #, 10]] &)]) &, candidates,
Length@# > 0 &]; seeds = Flatten@seeds</langsyntaxhighlight>
{{out}}
<pre>{196,879,1997,7059,9999}</pre>
<pre>
{196,879,1997,7059,9999}</pre>
Note, here only 10 iterations were done for comparison. While reducing the number of
iterations is clearly effective for intergers less than 10,000 this may not be sufficient
Line 2,069 ⟶ 2,322:
 
The number of related Lychrel numbers is:
<syntaxhighlight lang Mathematica="mathematica">Length@candidates - Length@seeds</langsyntaxhighlight>
{{out}}
<pre>244
</pre>
The Lycrel numbers that are also palindromes are:
<langsyntaxhighlight Mathematicalang="mathematica">Cases[candidates, _?(palindromeQ@# &)]</langsyntaxhighlight>
{{out}}
<pre>{4994,8778,9999}
</pre>
 
=={{Headerheader|PascalNim}}==
It would be possible to work with big numbers thanks to some third party library, but there is actually no need for this. With big numbers, we would have to convert from Int to string and back from string to Int which is costly. It seems better to work with a sequence of digits (not chars!) and to define a function "addReverse" and a function "inc". This way, we minimize the number of conversions to strings and avoid completely the conversion from string to Int.
 
The program runs in 20-30 ms and there is probably still some room for optimizations.
 
<syntaxhighlight lang="nim">import algorithm, sequtils, strformat, strutils, tables
 
type
 
Digit = range[0..9]
Number = seq[Digit] # Number as a sequence of digits (unit at index 0).
 
# Structure used to find the candidates for Lychrel numbers.
Candidates = object
seeds: seq[Number] # List of possible seeds.
linked: Table[Number, Number] # Maps a number to a smallest number in a sequence.
 
 
####################################################################################################
# Conversions.
 
func toInt(n: Number): Natural =
## Convert a Number to an int. No check is done for overflow.
for i in countdown(n.high, 0):
result = 10 * result + n[i]
 
func `$`(n: Number): string =
## Return the string representation of a Number.
reversed(n).join()
 
func `$`(s: seq[Number]): string =
## Return the string representation of a sequence of Numbers.
s.mapIt($it).join(" ")
 
 
####################################################################################################
# Operations on Numbers.
 
func addReverse(n: var Number) =
## Add a Number to its reverse.
var carry = 0
var high = n.high
var r = reversed(n)
for i in 0..high:
var sum = n[i] + r[i] + carry
if sum >= 10:
n[i] = sum - 10
carry = 1
else:
n[i] = sum
carry = 0
if carry != 0: n.add carry
 
func inc(a: var Number) =
## Increment a Number by one.
for item in a.mitems:
let sum = item + 1
if sum >= 10:
item = sum - 10
else:
item = sum
return # No carry: stop adding.
a.add 1 # Add last carry.
 
 
####################################################################################################
# Operations related to Lychrel numbers.
 
func isPalindromic(n: Number): bool =
## Check if a Number is palindromic.
for i in 0..(n.high div 2):
if n[i] != n[n.high - i]: return false
result = true
 
 
func isRelatedLychrel(candidates: Candidates; n: Number): bool =
## Check if a Number is a Lychrel related number.
 
var val = candidates.linked[n]
# Search for the first value in a list of linked values.
while val in candidates.linked: val = candidates.linked[val]
# If the first value is a seed, "n" is related to it.
result = val in candidates.seeds
 
 
func relatedCount(candidates: Candidates; maxlen: Positive): int =
## Return the number of related Lychrel numbers with length <= maxlen.
# Loop on values which are linked to a smallest value.
for n in candidates.linked.keys:
if n.len <= maxlen and candidates.isRelatedLychrel(n): inc result
 
 
func palindromicLychrel(candidates: Candidates; maxlen: Positive): seq[int] =
## Return the list of palindromic Lychrel numbers with length <= maxlen.
 
# Search among seed Lychrel numbers.
for n in candidates.seeds:
if n.len <= maxlen and n.isPalindromic:
result.add n.toInt
# Search among related Lychrel numbers.
for n in candidates.linked.keys:
if n.len <= maxlen and n.isPalindromic and candidates.isRelatedLychrel(n):
result.add n.toInt
# Sort the whole list.
result.sort()
 
 
proc check(candidates: var Candidates; num: Number) =
## Check if a Number is a possible Lychrel number.
 
if num in candidates.linked: return # Already encountered: nothing to do.
var val = num
for _ in 1..500:
val.addReverse()
if val in candidates.linked:
# Set the linked value of "num" to that of "val".
candidates.linked[num] = candidates.linked[val]
return
if val.isPalindromic(): return # Don't store palindromic values as they may be seeds.
candidates.linked[val] = num
candidates.seeds.add num
 
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
var cand: Candidates
 
var num: Number = @[Digit(0)] # The Number to test.
for n in 1..10_000:
inc num
cand.check(num)
 
echo &"Found {cand.seeds.len} candidate seed Lychrel numbers between 1 and 10000."
echo "These candidate seed Lychrel numbers are: ", cand.seeds
echo &"Found {cand.relatedCount(4)} candidate related Lychrel numbers between 1 and 10000."
echo "Palindromic candidate Lychrel numbers between 1 and 10000 are: ", cand.palindromicLychrel(4)</syntaxhighlight>
 
{{out}}
<pre>Found 5 candidate seed Lychrel numbers between 1 and 10000.
These candidate seed Lychrel numbers are: 196 879 1997 7059 9999
Found 244 candidate related Lychrel numbers between 1 and 10000.
Palindromic candidate Lychrel numbers between 1 and 10000 are: @[4994, 8778, 9999]</pre>
 
=={{header|Pascal}}==
{{works with|Free Pascal}}
I use an array of byte.The trick is to add first, so i don't need to create a reversed number and only have to sum up one half and than correct the carry, which is most time consuming.
Line 2,087 ⟶ 2,484:
The main intention was to get below 1min for 100e6 ;-)
 
<langsyntaxhighlight lang="pascal">program p196;
{$IFDEF FPC}
{$R-}
Line 2,383 ⟶ 2,780:
user 0m48.579s
sys 0m0.012s
}</langsyntaxhighlight>
 
{{out}}
Line 2,395 ⟶ 2,792:
</pre>
 
=={{Headerheader|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use English;
use bigint;
use Const::Fast;
use Math::AnyNum qw(:overload);
 
const my $n_max => 10_000;
const my $iter_cutoff => 500;
my(@seq_dump, @seed_lychrels, @related_lychrels);
 
my @seq_dump = ();
my @seed_lychrels = ();
my @related_lychrels = ();
for (my $n=1; $n<=$n_max; $n++) {
my @seq = lychrel_sequence($n);
if (scalar(@seq)$iter_cutoff == $iter_cutoffscalar @seq) {
if (has_overlap(\@seq, \@seq_dump)) { push @related_lychrels, $n }
else { push @related_lychrelsseed_lychrels, $n; }
}
else {
push @seed_lychrels, $n;
}
@seq_dump = set_union(\@seq_dump, \@seq);
}
}
 
print "Number of seed Lychrels <= $n_max: ", scalar(@seed_lychrels), "\n";
printprintf "Seed%45s %s\n", "Number of seed Lychrels <= $n_max: ", join(q{, }, scalar @seed_lychrels), "\n";
printprintf "Number%45s of%s\n", related"Seed Lychrels <= $n_max: ", scalar(@related_lychrels) join ', "\n"', @seed_lychrels;
printprintf "Palindromes%45s among%s\n", seed"Number andof related Lychrels <= $n_max: ", scalar @related_lychrels;
printf "%45s %s\n", "Palindromes among seed and related <= $n_max:",
join(q{, },
join ', ', sort {$a <=> $b} grep { is_palindrome($ARG) } @seed_lychrels, @related_lychrels;
grep {is_palindrome($ARG)} (@seed_lychrels, @related_lychrels)),
"\n";
exit 0;
 
sub lychrel_sequence {
my $n = shift;
my @seq = ();
for (1 .. $iter_cutoff) {
return if is_palindrome($n = next_n($n));
ifpush @seq, (is_palindrome($n)) { return (); }
else { push @seq, $n; }
}
return @seq;
}
 
sub next_n { my $n = shift; $n + reverse($n) }
sub is_palindrome { my $n = shift; $n eq reverse($n) }
return $n + reverse($n . q{});
}
 
sub is_palindrome {
my $n = shift;
return $n eq reverse($n . q{});
}
 
sub has_overlap {
my ($a, $b) = @ARG;
my %h;
foreach my $k (@h{$a_})++ {for $h@{$ka}++; }
foreach myexists $k (@h{$b_}) {and return 1 iffor exists $h@{$kb}; }
return 0;
}
 
Line 2,461 ⟶ 2,842:
my ($a, $b) = @ARG;
my %h;
foreach$h{$_}++ myfor $k (@{$a}), @{ $h{$kb}++; }
keys %h;
foreach my $k (@{$b}) { $h{$k}++; }
}</syntaxhighlight>
return keys(%h);
}</lang>
{{out}}
<pre> Number of seed Lychrels <= 10000: 5
Seed Lychrels <= 10000: 196, 879, 1997, 7059, 9999
Number of related Lychrels <= 10000: 244
Palindromes among seed and related <= 10000: 4994, 8778, 9999</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">iterations</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">500</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">limit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10000</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">seeds</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">cache</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">temp</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;">iterations</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">palin</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">related</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</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: #000000;">limit</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">num</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">rev</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">palindrome</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">=</span><span style="color: #000000;">rev</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: #000000;">iterations</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">)</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: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">rev</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'0'</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">></span><span style="color: #008000;">'9'</span>
<span style="color: #000000;">num</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">-</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">*</span><span style="color: #000000;">10</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span> <span style="color: #008080;">then</span> <span style="color: #000000;">num</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"1"</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">num</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">temp</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;">num</span>
<span style="color: #000000;">rev</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">=</span><span style="color: #000000;">rev</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: #000000;">num</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">rev</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">no_match</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #000000;">num</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">palindrome</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">palin</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">palin</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">c</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;">cache</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">seed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cache</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #000080;font-style:italic;">-- check against previous found seeds</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">iterations</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;">string</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">temp</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: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seed</span><span style="color: #0000FF;">)></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">seed</span><span style="color: #0000FF;">=</span><span style="color: #000000;">ti</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">no_match</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #000000;">related</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</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;">no_match</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</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: #000000;">no_match</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">seeds</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seeds</span><span style="color: #0000FF;">,</span><span style="color: #000000;">num</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cache</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cache</span><span style="color: #0000FF;">,</span><span style="color: #000000;">temp</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;">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;">"%d lychrel seeds: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seeds</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seeds</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">", "</span><span style="color: #0000FF;">)})</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;">"related lychrel: %d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">related</span><span style="color: #0000FF;">)</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 lychrel palindromes: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">palin</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">palin</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">", "</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
{{out}}
Completes in under a second on desktop/Phix, but takes about 10s under pwa/p2js
<pre>
5 lychrel seeds: 196, 879, 1997, 7059, 9999
Number of seed Lychrels <= 10000: 5
related lychrel: 244
Seed Lychrels <= 10000: 196, 879, 1997, 7059, 9999
3 lychrel palindromes: 4994, 8778, 9999
Number of related Lychrels <= 10000: 244
Palindromes among seed and related <= 10000: 4994, 8778, 9999
</pre>
 
=={{header|Perl 6Picat}}==
<syntaxhighlight lang="picat">go =>
{{works with|Rakudo|2018.03}}
Limit = 500,
Lychrel = [],
Cache = new_set(), % caching the found Lychrel numbers
Seeds = [],
Palindromes = [],
foreach(N in 1..10_000)
if lychrel(N,Cache,Limit,Seed) then
Lychrel := Lychrel ++ [N],
if Seed then Seeds := Seeds ++ [N] end,
if rev(N) == N then Palindromes := Palindromes ++ [N] end
end
end,
 
println(num_lychrel_numbers=Seeds.len),
<lang perl6>my %lychrels;
my @ println(seeds;=Seeds),
my @ println(palindromes;=Palindromes),
println(num_palindromes=Palindromes.len),
my $count;
println(num_related=(Lychrel.len-Seeds.len)),
my $max = 500;
nl.
my $limit = '10_000';
my %seen;
 
table
for 1 .. $limit -> $int {
rev(N) = N.to_string().reverse().to_int().
my @test;
my $index = 0;
if $int.&is-lychrel {
%lychrels.push: ($int => @test).invert;
@palindromes.push: $int if $int == $int.flip;
$count++;
}
 
sub is-lychrel (Int $lN,Cache,Limit,Seed) {=>
Found = false, % true if we %seen{$l} orfound $index++a >non $maxLychrel {number
Seq = [N],
%seen{$_} = True for @test;
Seed1 = false,
return True;
OldHit = cond(Cache.has_key(N),true,false), % found a Lychrel number from cache
}
I = 0,
@test.push: my $m = $l + $l.flip;
while (OldHit == false,Found == false,I <= Limit)
return False if $m == $m.flip;
I := $m.&is-lychrel;I+1,
N := N + rev(N),
}
if Cache.has_key(N) then
}
OldHit := true
 
else
for %lychrels{*}»[0].unique.sort -> $ly {
my $next Seq := False;Seq ++ [N],
if N == rev(N) then Found := true end
for %lychrels -> $l {
end
for $l.value[1..*] -> $lt {
end,
$next = True and last if $ly == $lt;
if Found == false, OldHit == false then
last if $ly < $lt;
Seed1 := true, % this is a seed, so add all elements to the cache
}
foreach(S in Seq) Cache.put(S) end
last if $next;
}end,
Seed = Seed1,
next if $next;
% The check: have we found a Lyncrel number
@seeds.push: $ly;
(OldHit == true ; Found == false).</syntaxhighlight>
}
 
say " Number of Lychrel seed numbers < $limit: ", +@seeds;
say " Lychrel seed numbers < $limit: ", join ", ", @seeds;
say "Number of Lychrel related numbers < $limit: ", +$count - @seeds;
say " Number of Lychrel palindromes < $limit: ", +@palindromes;
say " Lychrel palindromes < $limit: ", join ", ", @palindromes;</lang>
 
{{out}}
<pre>num_lychrel_numbers = 5
<pre> Number of Lychrel seed numbers < 10_000: 5
seeds = Lychrel seed numbers < 10_000: [196, 879, 1997, 7059, 9999]
palindromes = [4994,8778,9999]
Number of Lychrel related numbers < 10_000: 244
num_palindromes = 3
Number of Lychrel palindromes < 10_000: 3
num_related = 244</pre>
Lychrel palindromes < 10_000: 4994, 8778, 9999</pre>
 
=={{header|Phix}}==
<lang Phix>constant iterations = 500,
limit = 10000
sequence seeds = {},
cache = {}
sequence temp = repeat(0,iterations)
sequence palin = {}
integer related = 0
 
for n=1 to limit do
string num = sprintf("%d",n),
rev = reverse(num)
bool palindrome = (num=rev)
for i=1 to iterations do
integer digit, carry = 0
for x=length(num) to 1 by -1 do
digit = num[x]+rev[x]+carry-'0'
carry = digit>'9'
num[x] = digit-carry*10
end for
if carry then num = "1" & num end if
temp[i] = num
rev = reverse(num)
if num=rev then exit end if
end for
if num!=rev then
bool no_match = true
num = sprintf("%d",n)
if palindrome then
palin = append(palin, num)
end if
for c=1 to length(cache) do
string seed = cache[c]
-- check against previous found seeds
for i=iterations to 1 by -1 do
string ti = temp[i]
if length(seed)>length(ti) then
exit
elsif seed=ti then
no_match = false
related += 1
exit
end if
end for
if no_match=false then exit end if
end for
if no_match then
seeds = append(seeds,num)
cache = append(cache,temp[$])
end if
end if
end for
printf(1,"%d lychrel seeds: %s\n",{length(seeds),join(seeds, ", ")})
printf(1,"related lychrel: %d\n",related)
printf(1,"%d lychrel palindromes: %s\n", {length(palin),join(palin, ", ")})</lang>
{{out}}
Completes in under a second
<pre>
5 lychrel seeds: 196, 879, 1997, 7059, 9999
related lychrel: 244
3 lychrel palindromes: 4994, 8778, 9999
</pre>
 
=={{Headerheader|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de pali? (N)
(let N (chop N)
(= N (reverse N)) ) )
Line 2,651 ⟶ 3,031:
(lychrel 10000)
 
(bye)</langsyntaxhighlight>
 
{{out}}
Line 2,665 ⟶ 3,045:
=={{header|PowerShell}}==
{{works with|PowerShell|4}}
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Test-Palindrome ( [String]$String )
{
Line 2,768 ⟶ 3,148:
return $LychrelNumbers
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
$Upto = 10000
$IterationLimit = 500
Line 2,780 ⟶ 3,160:
"Number of palindrome Lychrel numbers: " + $LychrelNumbers.Palindromes.Count
" Palindrome Lychrel numbers: " + ( $LychrelNumbers.Palindromes -join ", " )
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,791 ⟶ 3,171:
</pre>
 
=={{Headerheader|PythonProlog}}==
{{trans|D}}
<lang python>from __future__ import print_function
{{works with|SWI Prolog}}
<syntaxhighlight lang="prolog">reverse_number(Number, Rev):-
reverse_number(Number, 0, Rev).
 
reverse_number(0, Rev, Rev):-!.
reverse_number(N, R, Rev):-
R1 is R * 10 + N mod 10,
N1 is N // 10,
reverse_number(N1, R1, Rev).
 
lychrel(N, M, _, [], [], []):-
M > N,
!.
lychrel(N, M, Cache, Seeds, Related, Palindromes):-
reverse_number(M, R),
lychrel_sequence(M, 0, M, R, Cache, Sequence, Result),
update_cache(Cache, Sequence, Result, Cache1),
M1 is M + 1,
(Result == 0 ->
S = Seeds, Rel = Related, P = Palindromes
;
(R == M ->
Palindromes = [M|P]
;
Palindromes = P),
(Result == M ->
Seeds = [M|S], Related = Rel
;
Seeds = S, Related = [M|Rel])),
lychrel(N, M1, Cache1, S, Rel, P).
 
update_cache(Cache, [], _, Cache):-!.
update_cache(Cache, [S|Seq], Result, Cache2):-
put_assoc(S, Cache, Result, Cache1),
update_cache(Cache1, Seq, Result, Cache2).
 
lychrel_sequence(N, 500, _, _, _, [], N):-!.
lychrel_sequence(N, I, Sum, Rev, Cache, [Sum1|Sequence], Result):-
I1 is I + 1,
Sum1 is Sum + Rev,
reverse_number(Sum1, Rev1),
(((Rev1 == Sum1, Result = 0) ; get_assoc(Sum1, Cache, Result)) ->
Sequence = []
;
lychrel_sequence(N, I1, Sum1, Rev1, Cache, Sequence, Result)).
 
lychrel(N):-
empty_assoc(Cache),
lychrel(N, 1, Cache, Seeds, Related, Palindromes),
length(Seeds, Num_seeds),
length(Related, Num_related),
writef('number of seeds: %w\n', [Num_seeds]),
writef('seeds: %w\n', [Seeds]),
writef('number of related: %w\n', [Num_related]),
writef('palindromes: %w\n', [Palindromes]).
 
main:-
lychrel(10000).</syntaxhighlight>
 
{{out}}
<pre>
number of seeds: 5
seeds: [196,879,1997,7059,9999]
number of related: 244
palindromes: [4994,8778,9999]
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">from __future__ import print_function
 
def add_reverse(num, max_iter=1000):
Line 2,839 ⟶ 3,288:
pals = [x for x in lychrel + l_related if x == reverse_int(x)]
print(' Number of Lychrel palindromes:', len(pals))
print(' Lychrel palindromes:', ', '.join(str(n) for n in pals))</langsyntaxhighlight>
 
{{out}}
Line 2,850 ⟶ 3,299:
 
If we test the numbers in ascending order, many of them would have been encountered when checking smaller numbers (i.e. 10 is seen when testing 5), caching them causes a large performance boost, more so with larger ranges.
<langsyntaxhighlight lang="python">from __future__ import print_function
 
def rev(n): return int(str(n)[::-1])
Line 2,883 ⟶ 3,332:
print("%d Lychel seeds:"%len(seeds), seeds)
print("%d Lychel related" % len(related))
print("%d Lychel palindromes:" % len(palin), palin)</langsyntaxhighlight>
 
=={{Headerheader|RacketR}}==
<syntaxhighlight lang="rsplus">
library(gmp)
library(magrittr)
 
cache <- NULL
 
cache_reset <- function() { cache <<- new.env(TRUE, emptyenv()) }
cache_set <- function(key, value) { assign(key, value, envir = cache) }
cache_get <- function(key) { get(key, envir = cache, inherits = FALSE) }
cache_has_key <- function(key) { exists(key, envir = cache, inherits = FALSE) }
 
# Initialize the cache
cache_reset()
 
isPalindromic <- function(num) {
paste0(unlist(strsplit(num,"")), collapse = "") ==
paste0(rev(unlist(strsplit(num,""))),collapse = "")
}
 
 
aStep <- function(num) {
num %>%
strsplit("") %>%
unlist() %>%
rev() %>%
paste0(collapse = "") %>%
sub("^0+","",.) %>%
as.bigz() %>%
'+'(num) %>%
as.character
}
 
max_search <- 10000
limit <- 500
related <- 0
lychrel <- vector("numeric")
palindrome_lychrel <- vector("numeric")
 
for (candidate in 1:max_search) {
n <- as.character(candidate)
found <- TRUE
for (iteration in 1:limit) {
n <- aStep(n)
if (cache_has_key(n)) {
related <- related + 1
found <- FALSE
if (isPalindromic(as.character(candidate))) palindrome_lychrel <- append(palindrome_lychrel, candidate)
break
}
if (isPalindromic(n)) {
found <- FALSE
break
}
}
if (found) {
if (isPalindromic(as.character(candidate))) palindrome_lychrel <- append(palindrome_lychrel, candidate)
lychrel <- append(lychrel,candidate)
seeds <- seeds + 1
n <- as.character(candidate)
for (iteration in 1:limit) {
cache_set(n,"seen")
n <- aStep(n)
}
}
}
cat("Lychrel numbers in the range [1, ",max_search,"]\n", sep = "")
cat("Maximum iterations =",limit,"\n")
cat("Number of Lychrel seeds:",length(lychrel),"\n")
cat("Lychrel numbers:",lychrel,"\n")
cat("Number of related Lychrel numbers found:",related,"\n")
cat("Number of palindromic Lychrel numbers:",length(palindrome_lychrel),"\n")
cat("Palindromic Lychrel numbers:",palindrome_lychrel,"\n")
</syntaxhighlight>
{{out}}
<pre>
Lychrel numbers in the range [1, 10000]
Maximum iterations = 500
Number of Lychrel seeds: 5
Lychrel numbers: 196 879 1997 7059 9999
Number of related Lychrel numbers found: 244
Number of palindromic Lychrel numbers: 3
Palindromic Lychrel numbers: 4994 8778 9999
</pre>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket
(require racket/splicing)
 
Line 2,946 ⟶ 3,480:
Palindromic Lychrel numbers: ~a~%
EOS
(reverse seeds/r) (length seeds/r) n-relateds (reverse palindromes/r)))</langsyntaxhighlight>
 
{{out}}
Line 2,953 ⟶ 3,487:
Palindromic Lychrel numbers: ((4994 (related)) (8778 (related)) (9999 (seed)))</pre>
 
=={{Headerheader|REXXRaku}}==
(formerly Perl 6)
<lang rexx>/*REXX program finds and displays Lychrel numbers, related numbers, and palindromes. */
{{works with|Rakudo|2018.03}}
 
<syntaxhighlight lang="raku" line>my %lychrels;
my @seeds;
my @palindromes;
my $count;
my $max = 500;
my $limit = '10_000';
my %seen;
 
for 1 .. $limit -> $int {
my @test;
my $index = 0;
if $int.&is-lychrel {
%lychrels.push: ($int => @test).invert;
@palindromes.push: $int if $int == $int.flip;
$count++;
}
 
sub is-lychrel (Int $l) {
if %seen{$l} or $index++ > $max {
%seen{$_} = True for @test;
return True;
}
@test.push: my $m = $l + $l.flip;
return False if $m == $m.flip;
$m.&is-lychrel;
}
}
 
for %lychrels{*}»[0].unique.sort -> $ly {
my $next = False;
for %lychrels -> $l {
for $l.value[1..*] -> $lt {
$next = True and last if $ly == $lt;
last if $ly < $lt;
}
last if $next;
}
next if $next;
@seeds.push: $ly;
}
 
say " Number of Lychrel seed numbers < $limit: ", +@seeds;
say " Lychrel seed numbers < $limit: ", join ", ", @seeds;
say "Number of Lychrel related numbers < $limit: ", +$count - @seeds;
say " Number of Lychrel palindromes < $limit: ", +@palindromes;
say " Lychrel palindromes < $limit: ", join ", ", @palindromes;</syntaxhighlight>
 
{{out}}
<pre> Number of Lychrel seed numbers < 10_000: 5
Lychrel seed numbers < 10_000: 196, 879, 1997, 7059, 9999
Number of Lychrel related numbers < 10_000: 244
Number of Lychrel palindromes < 10_000: 3
Lychrel palindromes < 10_000: 4994, 8778, 9999</pre>
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX program finds and displays Lychrel numbers, related numbers, and palindromes. */
parse arg high limit . /*obtain optional argument from the CL.*/
if high='' | high=="," then high= 10000 /*Not specified? Then use the default.*/
if limit='' | limit=="," then limit= 500 /*Not specified?" Then use the default. " " " " " */
numeric digits limit % 2 /*ensure enough decimal digits for adds*/
T.= 0; @.= T.; #.=@.; w= length(high) /*W: is used for formatting numbers. */
Line 2,977 ⟶ 3,569:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
Lychrel: procedure expose limit @. #. T.; parse arg x 1 z /*set X and Z to argument 1.*/
rels= 0 /*# related numbers (so far)*/
do limit; z= z + reverse(z) /*add the reverse of Z ··· */
Line 2,989 ⟶ 3,581:
T._= 1 /*mark number as "related".*/
end /*a*/
return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Found in the range 1 to 10000 (limiting searches to 1000500 steps):
 
5 Lychrel numbers: 196 879 1997 7059 9999
Line 2,998 ⟶ 3,590:
3 Lychrel palindromes: 4994 8778 9999
</pre>
 
=={{header|RPL}}==
{{works with|HP|49}}
« 0
'''WHILE''' OVER '''REPEAT''' 10 * SWAP 10 IDIV2 ROT + '''END'''
NIP
» '<span style="color:blue">IREVERSE</span>' STO
« { } DUP DUP2 500 0 → seeds related current palych stop counts
« 1 10000 '''FOR''' n
1 CF { } 'current' STO <span style="color:grey"> @ flag 1 set = n is not a Lychrel seed</span>
n DUP <span style="color:blue">IREVERSE</span>
'''IF''' DUP2 == '''THEN''' 2 SF '''ELSE''' 2 CF '''END''' <span style="color:grey">@ flag 2 set = n is palindromic</span>
1 stop '''FOR''' j
+ 'current' OVER STO+
'''IF''' related OVER POS '''THEN'''
'related' current STO+ 'counts' (0,1) STO+
'''IF''' 2 FS? '''THEN''' 'palych' n STO+ '''END'''
1 SF stop 'j' STO
'''END'''
DUP <span style="color:blue">IREVERSE</span>
'''IF''' DUP2 == '''THEN''' 1 SF stop 'j' STO '''END'''
'''NEXT''' DROP2
'''IF''' 1 FC? '''THEN'''
'related' current STO+ 'counts' 1 STO+ 'seeds' n STO+
'''IF''' 2 FS? '''THEN''' 'palych' n STO+ '''END'''
'''END'''
'''NEXT'''
seeds counts palych
» » '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
3: {196 879 1997 7059 9999}
2: (5.,244.)
1: {4994 8778 9999}
</pre>
Results are identical when the loop limit is set at 50 instead of 500.
 
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">require 'set'
 
def add_reverse(num, max_iter=1000)
Line 3,050 ⟶ 3,679:
pals = (lychrel + l_related).select{|x| palindrome?(x)}.sort
puts " Number of Lychrel palindromes: #{pals.length}"
puts " Lychrel palindromes: #{pals}"</langsyntaxhighlight>
 
{{out}}
Line 3,075 ⟶ 3,704:
 
'''src/main.rs'''
<langsyntaxhighlight lang="rust">extern crate num;
use num::FromPrimitive;
use num::bigint::BigInt;
Line 3,192 ⟶ 3,821:
println!("Number of Lychrel palindromes: {}", palindrome_lychrels.len());
print_nums("Lychrel palindromes: ", &palindrome_lychrels);
}</langsyntaxhighlight>
 
{{out}}
Line 3,204 ⟶ 3,833:
=={{header|Scala}}==
Using a '''Map''' to prevent duplicate values in the Lychrel sequence when determining seeds.
<langsyntaxhighlight lang="scala">import scala.collection.mutable.LinkedHashMap
 
val range = 1 to 10000
Line 3,263 ⟶ 3,892:
println( s"\tRelated Count: ${related.size}" )
println( s"\t Palindromes: (${lychrelPals.mkString(", ")})")
}</langsyntaxhighlight>
 
{{out}}
Line 3,275 ⟶ 3,904:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">var (
lychrels = [],
palindromes = [],
Line 3,321 ⟶ 3,950:
say ("Number of Lychrel related numbers < 10_000: ", lychrels.len - seeds.len)
say (" Number of Lychrel palindromes < 10_000: ", palindromes.len)
say (" Lychrel palindromes < 10_000: ", palindromes.join(', '))</langsyntaxhighlight>
{{out}}
<pre>
Line 3,335 ⟶ 3,964:
{{libheader|AttaSwift's BigInt}}
 
<langsyntaxhighlight lang="swift">import BigInt
 
public struct Lychrel<T: ReversibleNumeric & CustomStringConvertible>: Sequence, IteratorProtocol {
Line 3,433 ⟶ 4,062:
print("Lychrel seeds found: \(seeds.sorted())")
print("Number of related Lychrel nums found: \(related.count)")
print("Lychrel palindromes found: \(seeds.union(related).filter(isPalindrome).sorted())")</langsyntaxhighlight>
 
{{out}}
Line 3,443 ⟶ 4,072:
Lychrel palindromes found: [4994, 8778, 9999]</pre>
 
=={{header|R}}==
<lang rsplus>
library(gmp)
library(magrittr)
 
cache <- NULL
 
cache_reset <- function() { cache <<- new.env(TRUE, emptyenv()) }
cache_set <- function(key, value) { assign(key, value, envir = cache) }
cache_get <- function(key) { get(key, envir = cache, inherits = FALSE) }
cache_has_key <- function(key) { exists(key, envir = cache, inherits = FALSE) }
 
# Initialize the cache
cache_reset()
 
isPalindromic <- function(num) {
paste0(unlist(strsplit(num,"")), collapse = "") ==
paste0(rev(unlist(strsplit(num,""))),collapse = "")
}
 
 
aStep <- function(num) {
num %>%
strsplit("") %>%
unlist() %>%
rev() %>%
paste0(collapse = "") %>%
sub("^0+","",.) %>%
as.bigz() %>%
'+'(num) %>%
as.character
}
 
max_search <- 10000
limit <- 500
related <- 0
lychrel <- vector("numeric")
palindrome_lychrel <- vector("numeric")
 
for (candidate in 1:max_search) {
n <- as.character(candidate)
found <- TRUE
for (iteration in 1:limit) {
n <- aStep(n)
if (cache_has_key(n)) {
related <- related + 1
found <- FALSE
if (isPalindromic(as.character(candidate))) palindrome_lychrel <- append(palindrome_lychrel, candidate)
break
}
if (isPalindromic(n)) {
found <- FALSE
break
}
}
if (found) {
if (isPalindromic(as.character(candidate))) palindrome_lychrel <- append(palindrome_lychrel, candidate)
lychrel <- append(lychrel,candidate)
seeds <- seeds + 1
n <- as.character(candidate)
for (iteration in 1:limit) {
cache_set(n,"seen")
n <- aStep(n)
}
}
}
cat("Lychrel numbers in the range [1, ",max_search,"]\n", sep = "")
cat("Maximum iterations =",limit,"\n")
cat("Number of Lychrel seeds:",length(lychrel),"\n")
cat("Lychrel numbers:",lychrel,"\n")
cat("Number of related Lychrel numbers found:",related,"\n")
cat("Number of palindromic Lychrel numbers:",length(palindrome_lychrel),"\n")
cat("Palindromic Lychrel numbers:",palindrome_lychrel,"\n")
</lang>
{{out}}
<pre>
Lychrel numbers in the range [1, 10000]
Maximum iterations = 500
Number of Lychrel seeds: 5
Lychrel numbers: 196 879 1997 7059 9999
Number of related Lychrel numbers found: 244
Number of palindromic Lychrel numbers: 3
Palindromic Lychrel numbers: 4994 8778 9999
</pre>
=={{header|Tcl}}==
 
Line 3,533 ⟶ 4,078:
As we collect Lychrel numbers, we can save some time by storing all the members of their orbits in a hash table so that related numbers can be quickly identified. This is what the <tt>$visited</tt> variable is for: using the keys of a dictionary (or on earlier Tcl versions, an array) for a hash table is a common trick in Tcl. Native bignums mean we don't have to worry about overflow
 
<langsyntaxhighlight Tcllang="tcl">proc pal? {n} {
expr {$n eq [string reverse $n]}
}
Line 3,585 ⟶ 4,130:
}
 
lychrels</langsyntaxhighlight>
 
{{out}}
Line 3,594 ⟶ 4,139:
Count of related numbers: 244
Palindromic Lychrel and related numbers: 4994 8778 9999</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-big}}
{{libheader|Wren-set}}
<syntaxhighlight lang="wren">import "./big" for BigInt
import "./set" for Set
 
var iterations = 500
var limit = 10000
var bigLimit = BigInt.new(limit)
 
// In the sieve, 0 = not Lychrel, 1 = Seed Lychrel, 2 = Related Lychrel
var lychrelSieve = List.filled(limit + 1, 0)
var seedLychrels = []
var relatedLychrels = Set.new()
 
var isPalindrome = Fn.new { |bi|
var s = bi.toString
return s == s[-1..0]
}
 
var lychrelTest = Fn.new { |i, seq|
if (i < 1) return
var bi = BigInt.new(i)
for (j in 1..iterations) {
bi = bi + BigInt.new(bi.toString[-1..0])
seq.add(bi)
if (isPalindrome.call(bi)) return
}
for (j in 0...seq.count) {
if (seq[j] <= bigLimit) {
lychrelSieve[seq[j].toSmall] = 2
} else {
break
}
}
var sizeBefore = relatedLychrels.count
// if all of these can be added 'i' must be a seed Lychrel
relatedLychrels.addAll(seq.map { |i| i.toString }) // can't add BigInts directly to a Set
if (relatedLychrels.count - sizeBefore == seq.count) {
seedLychrels.add(i)
lychrelSieve[i] = 1
} else {
relatedLychrels.add(i.toString)
lychrelSieve[i] = 2
}
}
 
var seq = []
for (i in 1..limit) {
if (lychrelSieve[i] == 0) {
seq.clear()
lychrelTest.call(i, seq)
}
}
var related = lychrelSieve.count { |i| i == 2 }
System.print("Lychrel numbers in the range [1, %(limit)]")
System.print("Maximum iterations = %(iterations)")
System.print("\nThere are %(seedLychrels.count) seed Lychrel numbers, namely:")
System.print(seedLychrels)
System.print("\nThere are also %(related) related Lychrel numbers in this range.")
var palindromes = []
for (i in 1..limit) {
if (lychrelSieve[i] > 0 && isPalindrome.call(BigInt.new(i))) palindromes.add(i)
}
System.print("\nThere are %(palindromes.count) palindromic Lychrel numbers, namely:")
System.print(palindromes)</syntaxhighlight>
 
{{out}}
<pre>
Lychrel numbers in the range [1, 10000]
Maximum iterations = 500
 
There are 5 seed Lychrel numbers, namely:
[196, 879, 1997, 7059, 9999]
 
There are also 244 related Lychrel numbers in this range.
 
There are 3 palindromic Lychrel numbers, namely:
[4994, 8778, 9999]
</pre>
 
=={{header|zkl}}==
Line 3,599 ⟶ 4,226:
 
The Lychrel number chain is stored as a long string with '\0' separating each number, which we can then search to find relateds.
<langsyntaxhighlight lang="zkl">var BN=Import("zklBigNum");
 
// 192-->"887\01675\07436\013783\0..." ~60k bytes
Line 3,624 ⟶ 4,251:
}
seeds.apply("get",0)
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">lychrels:=[1..0d10_000].filter(lychrel).apply(fcn(n){ T(n,lychrel(n,True)) });
println("[1..10,000] contains ",lychrels.len()," Lychrel numbers.");
 
Line 3,633 ⟶ 4,260:
(n:=findSeeds(lychrels))
.println("<-- Lychrel seeds (%d) ==> %d related"
.fmt(n.len(),lychrels.len() - n.len()));</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits