Magic constant: Difference between revisions
(→{{header|Wren}}: Now uses new BigInt cube root function rather than Num version - still quick (17 ms).) |
(Added XPL0 example.) |
||
Line 280: | Line 280: | ||
10¹⁹ : 2,714,418 |
10¹⁹ : 2,714,418 |
||
10²⁰ : 5,848,036 |
10²⁰ : 5,848,036 |
||
</pre> |
|||
=={{header|XPL0}}== |
|||
A magic square of side N contains N^2 items. The sum of a sequence 1..N^2 |
|||
is given by: Sum = (N^2+1) * N^2 / 2. A grid row adds to the magic |
|||
constant, and N rows add to the Sum. Thus the magic constant = Sum/N = |
|||
(N^3+N)/2. |
|||
<lang XPL0>int N, X; |
|||
real M, Thresh, MC; |
|||
[Text(0, "First 20 magic constants:^M^J"); |
|||
for N:= 3 to 20+3-1 do |
|||
[IntOut(0, (N*N*N+N)/2); ChOut(0, ^ )]; |
|||
CrLf(0); |
|||
Text(0, "1000th magic constant: "); |
|||
N:= 1000+3-1; |
|||
IntOut(0, (N*N*N+N)/2); |
|||
CrLf(0); |
|||
Text(0, "Smallest order magic square with a constant greater than:^M^J"); |
|||
Thresh:= 10.; |
|||
M:= 3.; |
|||
Format(1, 0); |
|||
for X:= 1 to 10 do |
|||
[repeat MC:= (M*M*M+M)/2.; |
|||
M:= M+1.; |
|||
until MC > Thresh; |
|||
Text(0, "10^^"); |
|||
if X < 10 then ChOut(0, ^0); |
|||
IntOut(0, X); |
|||
Text(0, ": "); |
|||
RlOut(0, M-1.); |
|||
CrLf(0); |
|||
Thresh:= Thresh*10.; |
|||
]; |
|||
]</lang> |
|||
{{out}} |
|||
<pre> |
|||
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 |
|||
</pre> |
</pre> |
Revision as of 18:26, 9 November 2021
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
- Wikipedia: Magic constant
- OEIS: A006003 (Similar sequence, though it includes terms for 0, 1 & 2.)
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
<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 dup + 1 -
] 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
Julia
Uses the inverse of the magic constant function for the last part of the task. <lang julia>using Lazy
magic(x) = (1 + x^2) * x ÷ 2 magics = @>> Lazy.range() map(magic) filter(x -> x > 10) # first 2 values are filtered out println("First 20 magic constants: ", Int.(take(20, magics))) println("Thousandth magic constant is: ", collect(take(1000, magics))[end])
println("Smallest magic square with constant greater than:") for expo in 1:20
goal = big"10"^expo ordr = Int(floor((2 * goal)^(1/3))) + 1 println("10^", string(expo, pad=2), " ", ordr)
end
</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] Thousandth magic constant is: 503006505 Smallest magic square with 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
This uses Julia's approach for the final parts. <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:") for (i in 1..20) {
var goal = BigInt.ten.pow(i) var order = (goal * 2).icbrt + 1 Fmt.print("10$-2s : $,9i", superscript.call(i), order)
}</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
XPL0
A magic square of side N contains N^2 items. The sum of a sequence 1..N^2 is given by: Sum = (N^2+1) * N^2 / 2. A grid row adds to the magic constant, and N rows add to the Sum. Thus the magic constant = Sum/N = (N^3+N)/2. <lang XPL0>int N, X; real M, Thresh, MC; [Text(0, "First 20 magic constants:^M^J"); for N:= 3 to 20+3-1 do
[IntOut(0, (N*N*N+N)/2); ChOut(0, ^ )];
CrLf(0); Text(0, "1000th magic constant: "); N:= 1000+3-1; IntOut(0, (N*N*N+N)/2); CrLf(0); Text(0, "Smallest order magic square with a constant greater than:^M^J"); Thresh:= 10.; M:= 3.; Format(1, 0); for X:= 1 to 10 do
[repeat MC:= (M*M*M+M)/2.; M:= M+1.; until MC > Thresh; Text(0, "10^^"); if X < 10 then ChOut(0, ^0); IntOut(0, X); Text(0, ": "); RlOut(0, M-1.); CrLf(0); Thresh:= Thresh*10.; ];
]</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