Strange plus numbers: Difference between revisions
(+x86 nasm dos) |
|||
Line 281: | Line 281: | ||
=={{header|x86 Assembly}}== |
=={{header|x86 Assembly}}== |
||
A 16-bit solution for NASM under DOS. Assemble with <code>nasm -fbin strange.asm -o strange.com</code>. |
A 16-bit solution for NASM under DOS. Assemble with <code>nasm -fbin strange.asm -o strange.com</code>. The prime sieve up to 18 is hard-coded. |
||
<lang> org 100h |
<lang> org 100h |
Revision as of 15:00, 24 February 2021
n is a strange plus number if the sum of the first two digits is prime and the sum of the second two digits is also prime.
Where 100 < n < 500
APL
<lang APL>(∧⌿ 2 3 5 7 11 13 17 ∊⍨ 2 +⌿ 10 (⊥⍣¯1) X)/X←100+⍳399</lang>
- Output:
111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498
C
Generalized solution: a number if strange iff the sum of two consecutive digits is always prime. Numbers < 10 are considered non-strange.
<lang c>#include <stdio.h>
static int p[20];
void sieve(int n, int *a) {
int i, j; a[0] = a[1] = 0; for (i = 2; i < n; i++) a[i] = 1; for (i = 2; i < n; i++) { if (a[i]) { j = i*i; if (j >= n) return; for (; j < n; j += i) a[j] = 0; } }
}
int isstrange(long n) {
int k;
if (n < 10) return 0; for (; n >= 10; n /= 10) { k = n%100; k = (k/10) + (k%10); if (!p[k]) return 0; } return 1;
}
int main(void) {
long n; int k = 0;
sieve(20, p); for (n = 100; n <= 500; n++) { if (isstrange(n)) { printf("%d%c", n, ++k%10 ? ' ' : '\n'); } } return 0;
}</lang>
- Output:
111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498
Factor
<lang factor>USING: grouping grouping.extras io kernel math math.primes math.ranges math.text.utils prettyprint sequences ;
- strange+? ( n -- ? )
dup 10 < [ drop f ] [ 1 digit-groups [ + ] 2 clump-map [ prime? ] all? ] if ;
"Strange plus numbers in (100, 500):" print nl 100 500 (a,b) [ strange+? ] filter dup 10 group [ [ pprint bl ] each nl ] each nl length pprint " strange plus numbers found." print</lang>
- Output:
Strange plus numbers in (100, 500): 111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498 65 strange plus numbers found.
Haskell
<lang haskell>import Data.List (intercalate) import Data.List.Split (chunksOf) import Data.Numbers.Primes (isPrime)
STRANGE PLUS NUMBERS -----------------
allStrangePlus :: [Int] allStrangePlus = [n | n <- [100 .. 500], isStrangePlus n]
isStrangePlus :: Int -> Bool isStrangePlus =
let test = isPrime . sum . take 2 in ((&&) <$> test <*> (test . tail)) . digits
digits :: Int -> [Int] digits = fmap (read . return) . show
TEST -------------------------
main :: IO () main =
(putStrLn . intercalate "\n\n") [ "Strange Plus numbers found:", "(total " <> (show . length) allStrangePlus <> ")", "Full list:", unlines (unwords <$> chunksOf 10 (show <$> allStrangePlus)) ]</lang>
- Output:
Strange Plus numbers found: (total 65) Full list: 111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498
Python
Using sympy.isprime
<lang python>Python 3.8.5 (default, Sep 3 2020, 21:29:08) [MSC v.1916 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license()" for more information. >>> from sympy import isprime
>>> [x for x in range(101,500)
if isprime(sum(int(c) for c in str(x)[:2])) and isprime(sum(int(c) for c in str(x)[1:]))]
[111, 112, 114, 116, 120, 121, 123, 125, 129, 141, 143, 147, 149, 161, 165, 167, 202, 203, 205, 207, 211, 212, 214, 216, 230, 232, 234, 238, 250, 252, 256, 258, 292, 294, 298, 302, 303, 305, 307, 320, 321, 323, 325, 329, 341, 343, 347, 349, 383, 385, 389, 411, 412, 414, 416, 430, 432, 434, 438, 470, 474, 476, 492, 494, 498] >>> </lang>
Raku
<lang perl6>unit sub MAIN ($start = 100, $end = 500); put +$_, " matching numbers from $start to $end:\n", $_ given
($start .. $end).hyper(:256batch,:8degree).grep: { all .comb.rotor(2 => -1).map: { .sum.is-prime } };</lang>
- Output:
65 matching numbers from 100 to 500: 111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498
REXX
<lang rexx>/*REXX pgm lists strange+ integers (within a range); sum of adjacent dec. digs is prime.*/ parse arg LO HI . /*obtain optional arguments from the CL*/ if LO== | LO=="," then LO= 101 /*Not specified? Then use the default.*/ if HI== | HI=="," then HI= 499 /* " " " " " " */ !.= 0; !.2= 1; !.3= 1; !.5= 1; !.7= 1 /*build array of sums that are prime. */
!.11= 1; !.13= 1; !.17= 1; !.19= 1 /* " " " " " " " */
$= /*the list of strange+ numbers (so far)*/
- = 0 /* " number " " " " " */
do j=LO to HI; L= length(j) /*look for strange+ numbers in range. */ if L==1 then iterate /*Number too short? Then skip it. */
do k=1 for L-1 /*examine the difference in the digits.*/ parse var j =(k) y +1 z +1 /*get two adjacent decimal digits: Y Z */ sum= y + z /*sum of two adjacent decimal digits. */ if \!.sum then iterate j /*Sum not prime? Then skip this number*/ end /*k*/ #= # + 1 /*bump the number of "strange+" numbers*/ $= $ j /*append the number to the $ list. */ end /*j*/ /*stick a fork in it, we're all done. */
say # ' strange plus numbers found between ' LO " and " HI ' (inclusive)' say say strip($)</lang>
- output when using the default inputs:
65 strange plus numbers found between 101 and 499 (inclusive) 111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498
Ring
<lang ring> load "stdlib.ring"
row = 0 see "Strange plus numbers are:"
for n = 100 to 500
flag = 1 str = string(n) for m = 1 to len(str)-1 num1 = number(str[m]) num2 = number(str[m+1]) pr = num1+num2 if not isprime(pr) flag = 0 exit ok next if flag = 1 row = row + 1 if (row-1) % 11 = 0 see nl else see " " + str ok ok
next </lang>
- Output:
Strange plus numbers are: 112 114 116 120 121 123 125 129 141 143 149 161 165 167 202 203 205 207 211 212 216 230 232 234 238 250 252 256 258 292 298 302 303 305 307 320 321 323 325 329 343 347 349 383 385 389 411 412 414 416 432 434 438 470 474 476 492 494 498
Wren
Simple brute force is adequate for this. <lang ecmascript>var primes = [2, 3, 5, 7, 11, 13, 17] var count = 0 var d = [] System.print("Strange plus numbers in the open interval (100, 500) are:\n") for (i in 101..499) {
d.clear() var j = i while (j > 0) { d.add(j % 10) j = (j/10).floor } if (primes.contains(d[0] + d[1]) && primes.contains(d[1] + d[2])) { System.write("%(i) ") count = count + 1 if (count % 10 == 0) System.print() }
} if (count % 10 != 0) System.print() System.print("\n%(count) strange plus numbers in all.")</lang>
- Output:
Strange plus numbers in the open interval (100, 500) are: 111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498 65 strange plus numbers in all.
x86 Assembly
A 16-bit solution for NASM under DOS. Assemble with nasm -fbin strange.asm -o strange.com
. The prime sieve up to 18 is hard-coded.
<lang> org 100h
xor cx, cx mov si, 100
L1 mov di, si
xor bh, bh
L2 mov ax, di
div byte [i100] mov al, ah xor ah, ah div byte [i10] mov bl, al add bl, ah cmp byte [bx+p], 0 je L6 mov ax, di div byte [i10] xor ah, ah mov di, ax cmp al, 10 jae L2
mov ax, si mov di, dig
L3 div byte [i10]
add ah, 48 mov [di], ah xor ah, ah inc di test ax, ax jnz L3
L4 mov ah, 2
mov dl, [di-1] int 21h dec di cmp di, dig jne L4 mov ah, 2 mov dl, 32 inc cx cmp cl, 10 jne L5 xor cl, cl mov dl, 10
L5 int 21h
L6 inc si
cmp si, 500 jbe L1 int 20h
i10 db 10 i100 db 100 p db 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0 dig:</lang>
- Output:
111 112 114 116 120 121 123 125 129 141 143 147 149 161 165 167 202 203 205 207 211 212 214 216 230 232 234 238 250 252 256 258 292 294 298 302 303 305 307 320 321 323 325 329 341 343 347 349 383 385 389 411 412 414 416 430 432 434 438 470 474 476 492 494 498