Distinct palindromes within decimal numbers: Difference between revisions

m
m (→‎{{header|REXX}}: allowed the use of numbers/words of any length, not just the width of last entry.)
m (→‎{{header|Wren}}: Minor tidy)
 
(14 intermediate revisions by 9 users not shown)
Line 24:
=={{header|Factor}}==
{{works with|Factor|0.99 2021-02-05}}
<langsyntaxhighlight lang="factor">USING: formatting io kernel math math.ranges present prettyprint
sequences sequences.extras sets ;
 
Line 41:
1320267947849490361205695 }
[ dup dpal [ length 2 < ] reject empty? "%-25d %u\n" printf ]
each</langsyntaxhighlight>
{{out}}
<pre>
Line 86:
83071934127905179083 t
1320267947849490361205695 f
</pre>
 
=={{header|Go}}==
{{trans|Wren}}
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"sort"
"strings"
)
 
func substrings(s string) []string {
var ss []string
n := len(s)
for i := 0; i < n; i++ {
for j := 1; j <= n-i; j++ {
ss = append(ss, s[i:i+j])
}
}
return ss
}
 
func reversed(s string) string {
var sb strings.Builder
for i := len(s) - 1; i >= 0; i-- {
sb.WriteByte(s[i])
}
return sb.String()
}
 
func main() {
fmt.Println("Number Palindromes")
for i := 100; i <= 125; i++ {
var pals []string
ss := substrings(fmt.Sprintf("%d", i))
for _, s := range ss {
if s == reversed(s) {
pals = append(pals, s)
}
}
m := make(map[string]bool)
for _, pal := range pals {
m[pal] = true
}
pals = pals[:0]
for k := range m {
pals = append(pals, k)
}
sort.Slice(pals, func(i, j int) bool {
if len(pals[i]) == len(pals[j]) {
return pals[i] < pals[j]
}
return len(pals[i]) < len(pals[j])
})
fmt.Printf("%d %3s\n", i, pals)
}
nums := []string{
"9", "169", "12769", "1238769", "123498769", "12346098769", "1234572098769",
"123456832098769", "12345679432098769", "1234567905432098769", "123456790165432098769",
"83071934127905179083", "1320267947849490361205695",
}
fmt.Println("\nNumber Has no >= 2 digit palindromes")
for _, num := range nums {
tmp := substrings(num)
var ss []string
for _, t := range tmp {
if len(t) > 1 {
ss = append(ss, t)
}
}
none := true
for _, s := range ss {
if s == reversed(s) {
none = false
break
}
}
fmt.Printf("%-25s %t\n", num, none)
}
}</syntaxhighlight>
 
{{out}}
<pre>
Number Palindromes
100 [ 0 1 00]
101 [ 0 1 101]
102 [ 0 1 2]
103 [ 0 1 3]
104 [ 0 1 4]
105 [ 0 1 5]
106 [ 0 1 6]
107 [ 0 1 7]
108 [ 0 1 8]
109 [ 0 1 9]
110 [ 0 1 11]
111 [ 1 11 111]
112 [ 1 2 11]
113 [ 1 3 11]
114 [ 1 4 11]
115 [ 1 5 11]
116 [ 1 6 11]
117 [ 1 7 11]
118 [ 1 8 11]
119 [ 1 9 11]
120 [ 0 1 2]
121 [ 1 2 121]
122 [ 1 2 22]
123 [ 1 2 3]
124 [ 1 2 4]
125 [ 1 2 5]
 
Number Has no >= 2 digit palindromes
9 true
169 true
12769 true
1238769 true
123498769 true
12346098769 true
1234572098769 true
123456832098769 true
12345679432098769 true
1234567905432098769 true
123456790165432098769 true
83071934127905179083 true
1320267947849490361205695 false
</pre>
 
=={{header|jq}}==
'''Works with [[Jq|jq]]''' (but the second task requires a version with support for "big integer" literals)
<br>
'''Works with gojq, the Go implementation of jq''' (provided `keys_unsorted` is replaced by `keys`)
 
In this entry, except for 0 itself, palindromes involving leading 0s are ignored.
 
One feature of the implementation given here is that uniqueness is achieved without
any sorting; however, if gojq is used, then `keys` would have to be used, thus entailing a sort after distinctness has been achieved.
 
Note that for the second task, and for very large integers (greater than 2^53) in general, accurate results require
gojq, or a version of jq supporting "big integer" literals.
<syntaxhighlight lang="jq">
# input: an integer
# output a stream of distinct integers, each representing an admissible palindrome
 
def palindromes:
# input: an array
def is_palindrome: . == reverse;
def all_palindromes:
(tostring|explode)
| range(0; length) as $i
| range($i+1; length+1) as $j
| .[$i:$j] # candidate
| select(is_palindrome)
| implode
# trim leading 0s:
| if length > 1 then sub("^00*"; "") else . end
| select(length>0) ;
 
INDEX(all_palindromes; .) | keys_unsorted[] | tonumber;
 
def task1:
" i palindromes",
(range(100; 126)
| "\(.) \([palindromes]|join(" "))" );
def task2:
(9, 169, 12769, 1238769, 123498769, 12346098769, 1234572098769,
123456832098769, 12345679432098769, 1234567905432098769, 123456790165432098769,
83071934127905179083, 1320267947849490361205695)
| select( any(palindromes; . > 99) );
 
task1,
"\nThe integers amongst those in the problem statement that have 2 or more digits:",
task2</syntaxhighlight>
{{out}}
<pre>
i palindromes
100 1 0
101 1 101 0
102 1 0 2
103 1 0 3
104 1 0 4
105 1 0 5
106 1 0 6
107 1 0 7
108 1 0 8
109 1 0 9
110 1 11 0
111 1 11 111
112 1 11 2
113 1 11 3
114 1 11 4
115 1 11 5
116 1 11 6
117 1 11 7
118 1 11 8
119 1 11 9
120 1 2 0
121 1 121 2
122 1 2 22
123 1 2 3
124 1 2 4
125 1 2 5
 
The integers amongst those in the problem statement that have 2 or more digits:
1320267947849490361205695
</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">function allpalindromes(a::Vector{T}) where T
pals = Vector{Vector{T}}([[x] for x in a])
len = length(a)
Line 114 ⟶ 320:
println(rpad(n, 26), palindrome2plusfree(n))
end
</langsyntaxhighlight>{{out}}
<pre>
Number Palindromes
Line 158 ⟶ 364:
83071934127905179083 true
1320267947849490361205695 false
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[ContainsPalindromeQ]
ContainsPalindromeQ[n_Integer, minlength_ : 1, b_ : 10] := Select[DeleteDuplicates@Subsequences[IntegerDigits[n, b], {minlength, \[Infinity]}], PalindromeQ]
ContainsPalindromeQ /@ Range[100, 125] // Column
Length[ContainsPalindromeQ[#, 2]] > 0 & /@ {9, 169, 12769, 1238769,
123498769, 12346098769, 1234572098769, 123456832098769,
12345679432098769, 1234567905432098769, 123456790165432098769,
83071934127905179083, 1320267947849490361205695}</syntaxhighlight>
{{out}}
<pre>{{1},{0},{0,0}}
{{1},{0},{1,0,1}}
{{1},{0},{2}}
{{1},{0},{3}}
{{1},{0},{4}}
{{1},{0},{5}}
{{1},{0},{6}}
{{1},{0},{7}}
{{1},{0},{8}}
{{1},{0},{9}}
{{1},{0},{1,1}}
{{1},{1,1},{1,1,1}}
{{1},{2},{1,1}}
{{1},{3},{1,1}}
{{1},{4},{1,1}}
{{1},{5},{1,1}}
{{1},{6},{1,1}}
{{1},{7},{1,1}}
{{1},{8},{1,1}}
{{1},{9},{1,1}}
{{1},{2},{0}}
{{1},{2},{1,2,1}}
{{1},{2},{2,2}}
{{1},{2},{3}}
{{1},{2},{4}}
{{1},{2},{5}}
 
{False, False, False, False, False, False, False, False, False, False, False, False, True}</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import algorithm, sequtils, sets, strutils
 
iterator substrings(s: string): string =
## Yield the substrings of the given string.
for istart in 0..s.high:
for istop in istart..s.high:
yield s[istart..istop]
 
func isPalindrome(s: string): bool =
## Return true if "s" is a palindrome.
result = true
for i in 0..(s.high div 2):
if s[i] != s[s.high - i]: return false
 
func cmpPal(s1, s2: string): int =
## Compare two palindromes (used for sort).
result = cmp(s1.len, s2.len)
if result == 0:
result = cmp(s1[0], s2[0])
 
func palindromes(str: string): seq[string] =
## Return the sorted list of palindromes contained in "str".
var palSet: HashSet[string]
for s in substrings(str):
if s.isPalindrome: palSet.incl s
result = sorted(toSeq(palSet), cmpPal)
 
 
when isMainModule:
 
for n in 100..125:
echo n, ": ", palindromes($n).mapIt(it.align(3)).join(" ")
 
echo()
for s in ["9", "169", "12769", "1238769", "123498769", "12346098769",
"1234572098769", "123456832098769", "12345679432098769",
"1234567905432098769", "123456790165432098769",
"83071934127905179083", "1320267947849490361205695"]:
let pals2 = palindromes(s).filterIt(it.len >= 2)
let verb = if pals2.len == 0: " doesn't contain palindromes "
else: " contains at least one palindrome "
echo s, verb, "of two digits or more"</syntaxhighlight>
 
{{out}}
<pre>100: 0 1 00
101: 0 1 101
102: 0 1 2
103: 0 1 3
104: 0 1 4
105: 0 1 5
106: 0 1 6
107: 0 1 7
108: 0 1 8
109: 0 1 9
110: 0 1 11
111: 1 11 111
112: 1 2 11
113: 1 3 11
114: 1 4 11
115: 1 5 11
116: 1 6 11
117: 1 7 11
118: 1 8 11
119: 1 9 11
120: 0 1 2
121: 1 2 121
122: 1 2 22
123: 1 2 3
124: 1 2 4
125: 1 2 5
 
9 doesn't contain palindromes of two digits or more
169 doesn't contain palindromes of two digits or more
12769 doesn't contain palindromes of two digits or more
1238769 doesn't contain palindromes of two digits or more
123498769 doesn't contain palindromes of two digits or more
12346098769 doesn't contain palindromes of two digits or more
1234572098769 doesn't contain palindromes of two digits or more
123456832098769 doesn't contain palindromes of two digits or more
12345679432098769 doesn't contain palindromes of two digits or more
1234567905432098769 doesn't contain palindromes of two digits or more
123456790165432098769 doesn't contain palindromes of two digits or more
83071934127905179083 doesn't contain palindromes of two digits or more
1320267947849490361205695 contains at least one palindrome of two digits or more</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">#!/usr/bin/perl
 
# https://rosettacode.org/wiki/Distinct_Palindromes_Within_Decimal_Numbers
use strict;
use warnings;
 
for ( 100 .. 125 )
{
my %found;
/.+(?{$& eq reverse $& and $found{$&}++})(*FAIL)/;
print "$_ => @{[ sort { $a <=> $b } keys %found ]}\n"
}
 
/..+(??{$& == (reverse $&) ? '' : '(*FAIL)' })/ and
print "$_ has a palindrome of 2 or more\n"
for ' 9, 169, 12769, 1238769, 123498769, 12346098769, 1234572098769,
123456832098769, 12345679432098769, 1234567905432098769,
123456790165432098769, 83071934127905179083, 1320267947849490361205695'
=~ /\d+/g;</syntaxhighlight>
{{out}}
<pre>
100 => 00 0 1
101 => 0 1 101
102 => 0 1 2
103 => 0 1 3
104 => 0 1 4
105 => 0 1 5
106 => 0 1 6
107 => 0 1 7
108 => 0 1 8
109 => 0 1 9
110 => 0 1 11
111 => 1 11 111
112 => 1 2 11
113 => 1 3 11
114 => 1 4 11
115 => 1 5 11
116 => 1 6 11
117 => 1 7 11
118 => 1 8 11
119 => 1 9 11
120 => 0 1 2
121 => 1 2 121
122 => 1 2 22
123 => 1 2 3
124 => 1 2 4
125 => 1 2 5
1320267947849490361205695 has a palindrome of 2 or more
</pre>
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_all_palindromes</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;">longest</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
Line 198 ⟶ 579:
<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;">"\nNumber Has no &gt;2 digit palindromes\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">show_all_palindromes</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<!--</langsyntaxhighlight>-->
<!--</lang>-->
{{out}}
<pre>
Line 248 ⟶ 628:
=={{header|Raku}}==
A minor modification of the [[Longest_palindromic_substrings#Raku|Longest palindromic substrings]] task. As such, works for any string, not just integers.
<syntaxhighlight lang="raku" perl6line>use Sort::Naturally;
 
sub getpal ($str) {
Line 278 ⟶ 658:
123456832098769, 12345679432098769, 1234567905432098769,
123456790165432098769, 83071934127905179083, 1320267947849490361205695,
<Do these strings contain a minimum two character palindrome?></langsyntaxhighlight>
{{out}}
<pre>All palindromic substrings including (bizarrely enough) single characters:
Line 333 ⟶ 713:
 
=={{header|REXX}}==
This REXX version can handle strings or numbers, &nbsp; a hexadecimal string is included in the examples.
<syntaxhighlight lang="text">/*REXX programpgm finds distinct palindromes contained in substrings (of (decimal numbers#s or strings). */
parse arg LO HI mL $$ /*obtain optional arguments from the CL*/
if LO='' | LO="," then LO= 100 /*Not specified? Then use the default.*/
Line 341 ⟶ 721:
if $$='' | $$="," then $$= 9 169 12769 1238769 12346098769 1234572098769 123456832098769,
12345679432098769 1234567905432098769 123456790165432098769 ,
83071934127905179083 'deadbeef' /* (hexadecimal) */ 1320267947849490361205695,
'Do 1320267947849490361205695these strings contain a minimum two character /* special numbers.*/palindrome?',
'amanaplanacanalpanama' /*a man a plan a canal panama*/
w= length(HI) /*max width of LO ──► HI for alignment.*/
 
Line 349 ⟶ 730:
end /*j*/
 
w#= length( word($$, words($$); ) ) if #==0 then exit 0 /*findNo thespecial lengthwords/numbers? of theThen last special #exit.*/
 
if words($$)==0 then exit 0 /*No special words/numbers? Then exit.*/
do m=1 for #; w= max(w, length(word($$, m))) /*find max width string in $$*/
end /*m*/
say
do j=1 for words($$)#; z= word($$, j) /*obtain a string in the $$ list. */
#= Dpal(z, mL); w= max(w, length(z) ) /*get # distinct palindromes, minLen=mL*/
_= left(':', #>0); @has= ' has '; @of='of length'
say right(z, w) @has # " palindrome"s(#,,' ') @of mL "or more"_ space($)
Line 369 ⟶ 752:
end /*k*/
end /*j*/
return #</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 410 ⟶ 793:
123456790165432098769 has 0 palindromes of length 2 or more
83071934127905179083 has 0 palindromes of length 2 or more
deadbeef has 1 palindrome of length 2 or more: ee
1320267947849490361205695 has 3 palindromes of length 2 or more: 202 494 949
Do has 0 palindromes of length 2 or more
these has 1 palindrome of length 2 or more: ese
strings has 0 palindromes of length 2 or more
contain has 0 palindromes of length 2 or more
a has 0 palindromes of length 2 or more
minimum has 3 palindromes of length 2 or more: minim ini mum
two has 0 palindromes of length 2 or more
character has 1 palindrome of length 2 or more: ara
palindrome? has 0 palindromes of length 2 or more
amanaplanacanalpanama has 12 palindromes of length 2 or more: ama amanaplanacanalpanama manaplanacanalpanam ana anaplanacanalpana naplanacanalpan aplanacanalpa planacanalp lanacanal anacana nacan aca
</pre>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func palindromes(arr) {
gather {
for a in (0..arr.end), b in (a .. arr.end) {
var sublist = arr.items(a..b -> ...)
take(sublist) if (sublist == sublist.flip)
}
}.uniq
}
 
for n in (100..125) {
say "#{n} -> #{palindromes(n.digits).sort.map{.join}.sort_by{.len}.join(' ')}"
}
 
[9, 169, 12769, 1238769, 123498769, 12346098769, 1234572098769,
123456832098769, 12345679432098769, 1234567905432098769, 123456790165432098769,
83071934127905179083, 1320267947849490361205695, "amanaplanacanalpanama"].each {|n|
var p = palindromes(n.kind_of(Number) ? n.digits : n.chars).grep { .len >= 2}
say ("#{'%25s' % n} has #{'%2d' % p.len} palindromes of length 2 or more: ",
p.sort.map{.join}.sort_by{.len}.join(' '))
}</syntaxhighlight>
{{out}}
<pre>
100 -> 0 1 00
101 -> 0 1 101
102 -> 0 1 2
103 -> 0 1 3
104 -> 0 1 4
105 -> 0 1 5
106 -> 0 1 6
107 -> 0 1 7
108 -> 0 1 8
109 -> 0 1 9
110 -> 0 1 11
111 -> 1 11 111
112 -> 1 2 11
113 -> 1 3 11
114 -> 1 4 11
115 -> 1 5 11
116 -> 1 6 11
117 -> 1 7 11
118 -> 1 8 11
119 -> 1 9 11
120 -> 0 1 2
121 -> 1 2 121
122 -> 1 2 22
123 -> 1 2 3
124 -> 1 2 4
125 -> 1 2 5
9 has 0 palindromes of length 2 or more:
169 has 0 palindromes of length 2 or more:
12769 has 0 palindromes of length 2 or more:
1238769 has 0 palindromes of length 2 or more:
123498769 has 0 palindromes of length 2 or more:
12346098769 has 0 palindromes of length 2 or more:
1234572098769 has 0 palindromes of length 2 or more:
123456832098769 has 0 palindromes of length 2 or more:
12345679432098769 has 0 palindromes of length 2 or more:
1234567905432098769 has 0 palindromes of length 2 or more:
123456790165432098769 has 0 palindromes of length 2 or more:
83071934127905179083 has 0 palindromes of length 2 or more:
1320267947849490361205695 has 3 palindromes of length 2 or more: 202 494 949
amanaplanacanalpanama has 12 palindromes of length 2 or more: aca ama ana nacan anacana lanacanal planacanalp aplanacanalpa naplanacanalpan anaplanacanalpana manaplanacanalpanam amanaplanacanalpanama
</pre>
 
Line 418 ⟶ 875:
{{libheader|Wren-fmt}}
{{libheader|Wren-sort}}
<langsyntaxhighlight ecmascriptlang="wren">import "./seq" for Lst
import "./fmt" for Fmt
import "./sort" for Sort
 
var substrings = Fn.new { |s|
Line 454 ⟶ 911:
var none = !ss.any { |s| s == s[-1..0] }
Fmt.print("$-25s $s", num, none)
}</langsyntaxhighlight>
 
{{out}}
9,476

edits