Find palindromic numbers in both binary and ternary bases: Difference between revisions
Find palindromic numbers in both binary and ternary bases (view source)
Revision as of 12:56, 27 August 2022
, 1 year agosyntax highlighting fixup automation
(Picat constrain solver solution) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 22:
{{trans|Python}}
<
F baseN(=num, b)
Line 55:
L(pal23) pal_23(6)
print(pal23‘ ’baseN(pal23, 3)‘ ’baseN(pal23, 2))</
{{out}}
Line 69:
=={{header|Ada}}==
===Simple Technique (Brute Force)===
<
procedure Brute is
Line 95:
end if;
end loop;
end Brute;</
{{out}}
<pre> 0: 0(2), 0(3)
Line 111:
The code is then very fast and also very much readable than if we had done the bit manipulations by hand.
<
procedure Palindromic is
type Int is mod 2**64; -- the size of the unsigned values we will test doesn't exceed 64 bits
Line 159:
end loop;
end loop Process_Each_Power_Of_4;
end Palindromic;</
{{out}}
On a modern machine, (core i5 for example), this code, compiled with the -O3 and -gnatp options, takes less than 5 seconds to give the seven first palindromes smaller than 2^64.
Line 173:
On my machine, this gets the first five results practically instantaneously and the sixth about eight seconds later.
<
script o
property digits : {int mod base as integer}
Line 243:
end task
task()</
{{output}}
<
0 0 0
1 1 1
Line 252:
1422773 101011011010110110101 2200021200022
5415589 10100101010001010100101 101012010210101
90396755477 1010100001100000100010000011000010101 22122022220102222022122"</
=={{header|Arturo}}==
{{trans|Ada}}
<
digs2: digits.base:2 n
return digs2 = reverse digs2
Line 302:
]
pal23</
{{out}}
Line 315:
=={{header|C}}==
Per the observations made by the Ruby code (which are correct), the numbers must have odd number of digits in base 3 with a 1 at the middle, and must have odd number of digits in base 2.
<
typedef unsigned long long xint;
Line 396:
}
return 0;
}</
{{out}}
<pre>0 0(2) 0(3)
Line 411:
and then checked to see if they are palindromic in binary.<br/>
The first 6 numbers take about 1/10th of a second. The 7th number takes about 3 and a half minutes.
<
using System.Collections.Generic;
using System.Linq;
Line 493:
}
}</
{{out}}
<pre style="height:30ex;overflow:scroll">
Line 523:
=={{header|Common Lisp}}==
Unoptimized version
<
(string-equal str (reverse str)) )
Line 534:
(palindromep (format nil "~3R" i)) )
(format t "n:~a~:* [2]:~B~:* [3]:~3R~%" i)
(incf results) ))</
{{out}}
<pre>n:0 [2]:0 [3]:0
Line 546:
=={{header|D}}==
{{trans|C}}
<
bool isPalindrome2(ulong n) pure nothrow @nogc @safe {
Line 604:
}
}
}</
{{out}}
<pre>0 0(3) 0(2)
Line 616:
{{trans|Ruby}}
{{works with|Elixir|1.3}}
<
import Integer, only: [is_odd: 1]
Line 643:
end
Palindromic.task</
{{out}}
<pre> decimal ternary binary
Line 654:
=={{header|F_Sharp|F#}}==
<
// Find palindromic numbers in both binary and ternary bases. December 19th., 2018
let fG(n,g)=(Seq.unfold(fun(g,e)->if e<1L then None else Some((g%3L)*e,(g/3L,e/3L)))(n,g/3L)|>Seq.sum)+g+n*g*3L
Seq.concat[seq[0L;1L;2L];Seq.unfold(fun(i,e)->Some (fG(i,e),(i+1L,if i=e-1L then e*3L else e)))(1L,3L)]
|>Seq.filter(fun n->let n=System.Convert.ToString(n,2).ToCharArray() in n=Array.rev n)|>Seq.take 6|>Seq.iter (printfn "%d")
</syntaxhighlight>
{{out}}
Finding 6 takes no time.
Line 685:
=={{header|Factor}}==
This implementation uses the methods for reducing the search space discussed in the Ruby example.
<
lists.lazy literals math math.parser sequences tools.time ;
IN: rosetta-code.2-3-palindromes
Line 710:
] each ;
[ main ] time</
{{out}}
<pre>The first 6 numbers which are palindromic in both binary and ternary:
Line 744:
and check if they are also binary palindromes using the optimizations which have been noted in some
of the other language solutions :
<
'converts decimal "n" to its ternary equivalent
Line 816:
Print " seconds on i3 @ 2.13 GHz"
Print "Press any key to quit"
Sleep</
{{out}}
<pre>The first 6 numbers which are palindromic in both binary and ternary are :
Line 849:
{{trans|C}}
On my modest machine (Intel Celeron @1.6ghz) this takes about 30 seconds to produce the 7th palindrome. Curiously, the C version (GCC 5.4.0, -O3) takes about 55 seconds on the same machine. As it's a faithful translation, I have no idea why.
<
import (
Line 949:
}
}
}</
{{out}}
Line 991:
=={{header|Haskell}}==
<
import Data.List (transpose, unwords)
import Numeric (readInt, showIntAtBase)
Line 1,055:
showBase :: Integer -> Integer -> String
showBase base n = showIntAtBase base intToDigit n []</
{{Out}}
<pre>Decimal Ternary Binary
Line 1,067:
=={{header|J}}==
'''Solution:'''
<
toBase=: #.inv"0 NB. convert to base(s) in left arg
filterPalinBase=: ] #~ isPalin@toBase/ NB. palindromes for base(s)
Line 1,087:
end.
y{.res
)</
'''Usage:'''
<
0 1 6643 1422773
10 2 3 showBases find23Palindromes getfirst 6 NB. first 6 binary & ternary palindomes
Line 1,097:
1422773 101011011010110110101 2200021200022
5415589 10100101010001010100101 101012010210101
90396755477 1010100001100000100010000011000010101 22122022220102222022122</
=={{header|Java}}==
This takes a while to get to the 6th one (I didn't time it precisely, but it was less than 2 hours on an i7)
<
public static boolean isPali(String x){
return x.equals(new StringBuilder(x).reverse().toString());
Line 1,118:
}
}
}</
{{out}}
<pre>0, 0, 0
Line 1,130:
===ES6===
{{Trans|Haskell}}
<
'use strict';
Line 1,254:
)))
.map(unwords));
})();</
{{Out}}
<pre>Decimal Ternary Binary
Line 1,266:
=={{header|Julia}}==
{{trans|C}}
<
prin3online(n) = println(lpad(n, 15), lpad(string(n, base=2), 40), lpad(string(n, base=3), 30))
reversebase3(n) = (x = 0; while n != 0 x = 3x + (n %3); n = div(n, 3); end; x)
Line 1,315:
printpalindromes(6)
</
<pre>
Number Base 2 Base 3
Line 1,328:
=={{header|Kotlin}}==
{{trans|FreeBASIC}}
<
/** converts decimal 'n' to its ternary equivalent */
Line 1,399:
}
while (count < 6)
}</
{{out}}
<pre>The first 6 numbers which are palindromic in both binary and ternary are:
Line 1,428:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
Block[{digits},
If[Divisible[n, 3], {},
Line 1,437:
];
base2PalindromeQ[n_] := IntegerDigits[n, 2] === Reverse[IntegerDigits[n, 2]];
Select[Flatten[palindromify3 /@ Range[1000000]], base2PalindromeQ]</
{{out}}
Line 1,444:
=={{header|Nim}}==
{{trans|Ada}}
<
#---------------------------------------------------------------------------------------------------
Line 1,520:
let t0 = cpuTime()
findPal23()
echo fmt"\nTime: {cpuTime() - t0:.2f}s"</
{{out}}
Line 1,534:
=={{header|PARI/GP}}==
<
my(N=3^n);
forstep(i=N+1,2*N,[1,2],
Line 1,544:
)
};
print1("0, 1"); for(i=1,11,check(i))</
{{out}}
<pre>0, 1, 6643, 1422773, 5415589, 90396755477</pre>
Line 1,550:
=={{header|Perl}}==
{{libheader|ntheory}}
<
print "0 0 0\n"; # Hard code the 0 result
Line 1,561:
# Print results (including base 10) if base-2 palindrome
print fromdigits($b2,2)," $b3 $b2\n" if $b2 eq reverse($b2);
}</
{{out}}
<pre>0 0 0
Line 1,579:
that turned out noticeably slower.
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #000080;font-style:italic;">-- widths and limits for 32/64 bit running (see output below):</span>
Line 1,719:
<span style="color: #008080;">end</span> <span style="color: #008080;">while</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>
<!--</
{{out}}
32 bit:
Line 1,749:
=== much simpler version ===
(slightly but not alot faster)
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">to_base</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
Line 1,796:
<span style="color: #008080;">end</span> <span style="color: #008080;">while</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>
<!--</
{{out}}
<pre>
Line 1,811:
=== much faster version ===
Inspired by Scala 😏
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">to_base</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
Line 1,853:
<span style="color: #000000;">center</span><span style="color: #0000FF;">(</span><span style="color: #000000;">to_base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">A</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">3</span><span style="color: #0000FF;">),</span><span style="color: #000000;">145</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
{{out}}
<pre>
Line 1,892:
</pre>
=={{header|Picat}}==
<syntaxhighlight lang="picat">
import sat.
to_num(List, Base, Num) =>
Line 1,925:
printf("%w %s %s%n", Y, to_radix_string(Y,2), to_radix_string(Y,3))
end.
</syntaxhighlight>
Output:
<pre>0 0 0
Line 1,935:
=={{header|PicoLisp}}==
<
(if (=0 N)
(cons N)
Line 1,952:
(println N (pack B2) (pack B3))
(inc 'I) )
(inc 'N) ) )</
{{out}}
<pre>0 "0" "0"
Line 1,963:
=={{header|Python}}==
===Imperative===
<
digits = "0123456789abcdefghijklmnopqrstuvwxyz"
Line 1,996:
for pal23 in islice(pal_23(), 6):
print(pal23, baseN(pal23, 3), baseN(pal23, 2))</
{{out}}
<pre>0 0 0
Line 2,007:
===Functional===
{{Works with|Python|3.7}}
<
from itertools import (islice)
Line 2,181:
# MAIN ---
if __name__ == '__main__':
main()</
{{Out}}
<pre> Decimal Binary Ternary
Line 2,193:
=={{header|Racket}}==
<
(require racket/generator)
Line 2,279:
(map (curryr number->string 2) (for/list ((i 16) (p (in-producer (b-palindromes-generator 2)))) p))
(list "0" "1" "11" "101" "111" "1001" "1111" "10001" "10101" "11011"
"11111" "100001" "101101" "110011" "111111" "1000001")))</
{{out}}
<pre> 1: 0_10 0_3 0_2
Line 2,292:
Instead of searching for numbers that are palindromes in one base then checking the other, generate palindromic trinary numbers directly, then check to see if they are also binary palindromes (with additional simplifying constraints as noted in other entries). Outputs the list in decimal, binary and trinary.
<syntaxhighlight lang="raku"
my $pal = $p.base(3);
my $n = :3($pal ~ '1' ~ $pal.flip);
Line 2,302:
}
printf "%d, %s, %s\n", $_, .base(2), .base(3) for palindromes[^6];</
{{out}}
<pre>0, 0, 0
Line 2,328:
::* convert the decimal numbers to base 3,
::* ensure that the numbers in base 3 are palindromic.
<
digs=50; numeric digits digs /*biggest known B2B3 palindrome: 44 dig*/
parse arg maxHits .; if maxHits=='' then maxHits=6 /*use six as a limit.*/
Line 2,357:
if hits>2 then if hits//2 then #=#'0'
if hits<maxHits then return /*Not enough palindromes? Keep looking*/
exit /*stick a fork in it, we're all done. */</
{{out|output|text= when using the default input of: <tt> 7 </tt>}}
<pre> [1] 0 (decimal), ternary= 0
Line 2,383:
===version 2===
This REXX version takes advantage that the palindromic numbers (in both binary and ternary bases) ''seem'' to only have a modulus nine residue of 1, 5, 7, or 8. With this assumption, the following REXX program is about 25% faster.
<
digs=50; numeric digits digs /*biggest known B2B3 palindrome: 44 dig*/
parse arg maxHits .; if maxHits=='' then maxHits=6 /*use six as a limit.*/
Line 2,413:
if hits>2 then if hits//2 then #=#'0'
if hits<maxHits then return /*Not enough palindromes? Keep looking*/
exit /*stick a fork in it, we're all done. */</
{{out|output|text= is identical to the 1<sup>st</sup> REXX version.}}
=={{header|Ring}}==
<
# Project: Find palindromic numbers in both binary and ternary bases
Line 2,465:
return 0
ok
</syntaxhighlight>
{{out}}
<pre>
Line 2,490:
This program constructs base 3 palindromes using the above "rules" and checks if they happen to be binary palindromes.
<
y << 0
y << 1
Line 2,505:
n = pal23.next
puts "%2d: %12d %s %s" % [i, n, n.to_s(3).center(25), n.to_s(2).center(39)]
end</
{{out}}
<pre> decimal ternary binary
Line 2,518:
===Functional programmed, (tail) recursive===
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/ZYCqm7p/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/WIL3oAwYSRy4Kl918u13CA Scastie (remote JVM)].
<
import scala.compat.Platform.currentTime
Line 2,555:
println(s"Successfully completed without errors. [total ${currentTime - executionStartTime} ms]")
}</
===Fastest and high yields (17) solution 😏===
{{Out}}Best seen running in your browser either by [https://scastie.scala-lang.org/en0ZiqDETCuWO6avhTi9YQ Scastie (remote JVM)].
<
object FastPalindrome23 extends App {
Line 2,581:
println(s"${count} palindromes found.")
}</
{{Out}}
<pre>Decimal : 0 , Central binary digit: 0
Line 2,671:
=={{header|Scheme}}==
<
(scheme write)
(srfi 1 lists)) ; use 'fold' from SRFI 1
Line 2,722:
(r-number->string n 3)))
(newline))
(get-series 6))</
{{out}}
Line 2,734:
=={{header|Sidef}}==
{{trans|Perl}}
<
format.printf("decimal", "ternary", "binary")
format.printf(0, 0, 0)
Line 2,745:
format.printf(Num(b2, 2), b3, b2)
}
}</
{{out}}
<pre> decimal ternary binary
Line 2,759:
{{trans|C}}
<
func isPalin2(n: Int) -> Bool {
Line 2,860:
}
}
}</
{{out}}
Line 2,874:
=={{header|Tcl}}==
We can use <tt>[format %b]</tt> to format a number as binary, but ternary requires a custom proc:
<
while {$n} {
append r [expr {$n % 3}]
Line 2,881:
if {![info exists r]} {set r 0}
string reverse $r
}</
Identifying palindromes is simple. This form is O(n) with a large constant factor, but good enough:
<
The naive approach turns out to be very slow:
<
for {set i 0} {$find} {incr i} {
set b [format %b $i]
Line 2,899:
}
puts [time {task 4}]</
{{out}}
<pre>Palindrome: 0 (0) (0)
Line 2,910:
We can do much better than that by naively iterating the binary palindromes. This is nice to do in a coroutine:
<
proc 2pals {} {
Line 2,923:
yield ${a}1$b
}
}</
The binary strings emitted by this generator are not in increasing order, but for this particular task, that turns out to be unimportant.
Our main loop needs only minor changes:
<
coroutine gen apply {{} {yield; 2pals}}
while {$find} {
Line 2,942:
}
puts [time task]</
This version finds the first 6 in under 4 seconds, which is good enough for the task at hand:
{{out}}
Line 2,956:
=={{header|VBA}}==
<
'palindromes both in base3 and base2
'using Decimal data type to find number 6 and 7, although slowly
Line 3,089:
Debug.Print "Completed in"; (Time3 - Time1) / 1000; "seconds"
Application.ScreenUpdating = True
End Sub</
' 0 0 0 0
' 0 1 1 1
Line 3,105:
{{libheader|Wren-fmt}}
Just the first 6 palindromes as the 7th is too large for Wren to process without resorting to BigInts.
<
var isPalindrome2 = Fn.new { |n|
Line 3,178:
}
}
}</
{{out}}
Line 3,218:
{{trans|Ruby}}
VERY slow after six but does find it.
<
Walker.tweak(fcn(ri,r){ // references to loop start and count of palindromes
foreach i in ([ri.value..*]){
Line 3,230:
}
}.fp(Ref(3),Ref(3))).push(T(1,0),T(2,1)) // seed with first two results
}</
<
println("%2d: %,d == %.3B(3) == %.2B(2)".fmt(idx,n,n,n))
}</
{{out}}
<pre>
|