Magic constant: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|QB64}}: add comment)
(→‎{{header|Factor}}: five times faster)
Line 95: Line 95:
=={{header|Factor}}==
=={{header|Factor}}==
{{works with|Factor|0.99 2021-06-02}}
{{works with|Factor|0.99 2021-06-02}}
<lang factor>USING: formatting io kernel lists lists.lazy math math.functions
<lang factor>USING: formatting io kernel math math.functions.integer-logs
math.ranges prettyprint sequences tools.memory.private ;
math.ranges prettyprint sequences ;


: magic-constants ( -- list )
: magic ( m -- n ) dup sq 1 + 2 / * ;
3 lfrom [ dup sq 1 + 2 / * ] lmap-lazy ;

: smallest ( m -- n )
[ magic-constants 3 lfrom lzip ] dip
'[ first _ 10^ > ] lfilter car second ;


"First 20 magic constants:" print
"First 20 magic constants:" print
3 22 [a,b] [ bl ] [ magic pprint ] interleave nl
20 magic-constants ltake [ pprint bl ] leach nl
nl
nl
"1000th magic constant:" print
"1000th magic constant: " write 1002 magic .
999 magic-constants lnth commas print
nl
nl
"Smallest order magic square with a constant greater than:" print
"Smallest order magic square with a constant greater than:" print
1 0 20 [
20 [1,b] [ dup smallest commas "10^%02d: %s\n" printf ] each
[ 10 * ] dip
</lang>
[ dup magic pick < ] [ 1 + ] while
over integer-log10 over "10^%02d: %d\n" printf
] times 2drop</lang>
{{out}}
{{out}}
<pre>
<pre>
First 20 magic constants:
First 20 magic constants:
15 34 65 111 175 260 369 505 671 870 1105 1379 1695 2056 2465 2925 3439 4010 4641 5335
15 34 65 111 175 260 369 505 671 870 1105 1379 1695 2056 2465 2925 3439 4010 4641 5335


1000th magic constant:
1000th magic constant: 503006505
503,006,505


Smallest order magic square with a constant greater than:
Smallest order magic square with a constant greater than:
Line 131: Line 127:
10^07: 272
10^07: 272
10^08: 585
10^08: 585
10^09: 1,260
10^09: 1260
10^10: 2,715
10^10: 2715
10^11: 5,849
10^11: 5849
10^12: 12,600
10^12: 12600
10^13: 27,145
10^13: 27145
10^14: 58,481
10^14: 58481
10^15: 125,993
10^15: 125993
10^16: 271,442
10^16: 271442
10^17: 584,804
10^17: 584804
10^18: 1,259,922
10^18: 1259922
10^19: 2,714,418
10^19: 2714418
10^20: 5,848,036
10^20: 5848036
</pre>
</pre>



Revision as of 23:46, 8 November 2021

Magic constant is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

A magic square is a square grid containing consecutive integers from 1 to N², arranged so that every row, column and diagonal adds up to the same number. That number is a constant. There is no way to create a valid N x N magic square that does not sum to the associated constant.

EG

A 3 x 3 magic square always sums to 15.

    ┌───┬───┬───┐
    │ 2 │ 7 │ 6 │
    ├───┼───┼───┤
    │ 9 │ 5 │ 1 │
    ├───┼───┼───┤
    │ 4 │ 3 │ 8 │
    └───┴───┴───┘

A 4 x 4 magic square always sums to 34.

Traditionally, the sequence leaves off terms for n = 0 and n = 1 as the magic squares of order 0 and 1 are trivial; and a term for n = 2 because it is impossible to form a magic square of order 2.


Task
  • Starting at order 3, show the first 20 magic constants.
  • Show the 1000th magic constant. (Order 1003)
  • Find and show the order of the smallest N x N magic square whose constant is greater than 10¹ through 10¹⁰.


Stretch
  • Find and show the order of the smallest N x N magic square whose constant is greater than 10¹¹ through 10²⁰.


See also


Basic

QB64

<lang qbasic>$NOPREFIX

DIM order AS INTEGER DIM target AS INTEGER64

PRINT "First 20 magic constants:" FOR i = 3 TO 22

   PRINT USING "####,  "; MagicSum(i);
   IF i MOD 5 = 2 THEN PRINT

NEXT i PRINT PRINT USING "1000th magic constant: ##########,"; MagicSum(1002) PRINT PRINT "Smallest order magic square with a constant greater than:" FOR i = 1 TO 13 ' 64-bit integers can take us no further, unsigned or not

   target = 10 ^ i
   DO
       order = order + 1
   LOOP UNTIL MagicSum(order) > target
   PRINT USING "10^**: #####,"; i; order
   order = order * 2 - 1

NEXT i

FUNCTION MagicSum&& (n AS INTEGER)

   MagicSum&& = (n * n + 1) / 2 * n

END FUNCTION</lang>

Output:
First 20 magic constants:
   15     34     65    111    175
  260    369    505    671    870
1,105  1,379  1,695  2,056  2,465
2,925  3,439  4,010  4,641  5,335

1000th magic constant: 503,006,505

Smallest order magic square with a constant greater than:
10^*1:      3
10^*2:      6
10^*3:     13
10^*4:     28
10^*5:     59
10^*6:    126
10^*7:    272
10^*8:    585
10^*9:  1,260
10^10:  2,715
10^11:  5,849
10^12: 12,600
10^13: 27,145

Factor

Works with: Factor version 0.99 2021-06-02

<lang factor>USING: formatting io kernel math math.functions.integer-logs math.ranges prettyprint sequences ;

magic ( m -- n ) dup sq 1 + 2 / * ;

"First 20 magic constants:" print 3 22 [a,b] [ bl ] [ magic pprint ] interleave nl nl "1000th magic constant: " write 1002 magic . nl "Smallest order magic square with a constant greater than:" print 1 0 20 [

   [ 10 * ] dip
   [ dup magic pick < ] [ 1 + ] while
   over integer-log10 over "10^%02d: %d\n" printf

] times 2drop</lang>

Output:
First 20 magic constants:
15 34 65 111 175 260 369 505 671 870 1105 1379 1695 2056 2465 2925 3439 4010 4641 5335

1000th magic constant: 503006505

Smallest order magic square with a constant greater than:
10^01: 3
10^02: 6
10^03: 13
10^04: 28
10^05: 59
10^06: 126
10^07: 272
10^08: 585
10^09: 1260
10^10: 2715
10^11: 5849
10^12: 12600
10^13: 27145
10^14: 58481
10^15: 125993
10^16: 271442
10^17: 584804
10^18: 1259922
10^19: 2714418
10^20: 5848036

Raku

<lang perl6>use Lingua::EN::Numbers:ver<2.8+>;

my @magic-constants = lazy (3..∞).hyper.map: { (1 + .²) * $_ / 2 };

put "First 20 magic constants: ", @magic-constants[^20]»., say "1000th magic constant: ", @magic-constants[999]., say "\nSmallest order magic square with a constant greater than:";

(1..20).map: -> $p {printf "10%-2s: %s\n", $p.&super, comma 3 + @magic-constants.first( * > exp($p, 10), :k ) }</lang>

Output:
First 20 magic constants: 15 34 65 111 175 260 369 505 671 870 1,105 1,379 1,695 2,056 2,465 2,925 3,439 4,010 4,641 5,335
1000th magic constant: 503,006,505

Smallest order magic square with a constant greater than:
10¹ : 3
10² : 6
10³ : 13
10⁴ : 28
10⁵ : 59
10⁶ : 126
10⁷ : 272
10⁸ : 585
10⁹ : 1,260
10¹⁰: 2,715
10¹¹: 5,849
10¹²: 12,600
10¹³: 27,145
10¹⁴: 58,481
10¹⁵: 125,993
10¹⁶: 271,442
10¹⁷: 584,804
10¹⁸: 1,259,922
10¹⁹: 2,714,418
10²⁰: 5,848,036

Wren

Library: Wren-seq
Library: Wren-fmt
Library: Wren-big

<lang ecmascript>import "./seq" for Lst import "./fmt" for Fmt import "./big" for BigInt

var magicConstant = Fn.new { |n| (n*n + 1) * n / 2 }

var ss = ["\u2070", "\u00b9", "\u00b2", "\u00b3", "\u2074",

         "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"]

var superscript = Fn.new { |n| (n < 10) ? ss[n] : (n < 20) ? ss[1] + ss[n - 10] : ss[2] + ss[0] }

System.print("First 20 magic constants:") var mc20 = (3..22).map { |n| magicConstant.call(n) }.toList for (chunk in Lst.chunks(mc20, 10)) Fmt.print("$5d", chunk)

Fmt.print("\n1,000th magic constant: $,d", magicConstant.call(1002))

System.print("\nSmallest order magic square with a constant greater than:") var count = 1 var n = BigInt.three var power = BigInt.ten while (count <= 20) {

   if (magicConstant.call(n) > power) {
       Fmt.print("10$-2s : $,9i", superscript.call(count), n)
       power = power * 10
       count = count + 1
   }
   n = n.inc

}</lang>

Output:
First 20 magic constants:
   15    34    65   111   175   260   369   505   671   870
 1105  1379  1695  2056  2465  2925  3439  4010  4641  5335

1,000th magic constant: 503,006,505

Smallest order magic square with a constant greater than:
10¹  :         3
10²  :         6
10³  :        13
10⁴  :        28
10⁵  :        59
10⁶  :       126
10⁷  :       272
10⁸  :       585
10⁹  :     1,260
10¹⁰ :     2,715
10¹¹ :     5,849
10¹² :    12,600
10¹³ :    27,145
10¹⁴ :    58,481
10¹⁵ :   125,993
10¹⁶ :   271,442
10¹⁷ :   584,804
10¹⁸ : 1,259,922
10¹⁹ : 2,714,418
10²⁰ : 5,848,036