O'Halloran numbers

From Rosetta Code
Task
O'Halloran numbers
You are encouraged to solve this task according to the task description, using any language you may know.

For this task, for our purposes, a cuboid is a 3 dimensional object, with six rectangular faces, where all angles are right angles, opposite faces of the cuboid are equal, and where each dimension is a positive integer unit length. It will subsequently be referred to simply as a cuboid; but be aware that it references the above definition.

The surface area of a cuboid is two times the length times the width, plus two times the length times the height, plus two times the width times the height. A cuboid will always have an even integer surface area. The minimum surface area a cuboid may have is 6; one where the l, w, and h measurements are all 1.

  2 × ( l × w + w × h + h × l )
  2 × ( 1 × 1 + 1 × 1 + 1 × 1 ) = 6

Different cuboid configurations (may) yield different surface areas, but the surface area is always an integer and is always even.

A cuboid with l = 2, w = 1 h = 1 has a surface area of 10

  2 × ( 2 × 1 + 1 × 1 + 1 × 2 ) = 10

There is no configuration which will yield a surface area of 8.

There are 16 known even integer values below 1000 which can not be a surface area for any integer cuboid. It is conjectured, though not rigorously proved, that no others exist.

Task
  • Find and display the sixteen even integer values larger than 6 (the minimum cuboid area) and less than 1000

that can not be the surface area of a cuboid.

See also


ALGOL 68

As in the Phix and other samples, we only need to consider one arrangement of each l, b and h values.

BEGIN # find O'Halloran numbers - numbers that cannot be the surface area of  #
      #                           a cuboid with integer dimensions            #
    INT count        := 0;
    INT max area      = 1 000;
    INT half max area = max area OVER 2;
    FOR n FROM 8 BY 2 TO max area DO
        BOOL ohalloran := TRUE;
        FOR l TO half max area WHILE ohalloran DO
            FOR b FROM l TO half max area WHILE INT lb = l * b;
                                                lb < n AND ohalloran
            DO
                FOR h FROM b TO half max area WHILE INT bh = b * h, lh = l * h;
                                                    INT sum = 2 * ( lb + bh + lh );
                                                    sum <= n AND ( ohalloran := sum /= n )
                DO SKIP OD
            OD
        OD;
        IF ohalloran THEN
            print( ( " ", whole( n, 0 ) ) );
            count +:= 1
        FI
    OD
END
Output:
 8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

AppleScript

on OHalloranNumbers(max)
    script o
        property evens : {missing value, missing value}
    end script
    repeat with n from 6 to max by 2
        set end of o's evens to n
    end repeat
    set halfMax to max div 2
    set sixthMax to halfMax div 3
    repeat with x from 1 to sixthMax
        repeat with y from x to (sixthMax div x)
            repeat with halfArea from ((x + x + y) * y) to halfMax by (x + y)
                set o's evens's item halfArea to missing value
            end repeat
        end repeat
    end repeat
    return o's evens's integers
end OHalloranNumbers

OHalloranNumbers(1000 - 1)

(* Repeat logic condensed from:
    repeat with x from 1 to sixthMax
        repeat with y from x to sixthMax
            set xy to x * y
            if (xy > sixthMax) then exit repeat
            repeat with z from y to sixthMax
                set halfArea to xy + (x + y) * z
                if (halfArea > halfMax) then exit repeat
                set o's evens's item halfArea to missing value
            end repeat
        end repeat
    end repeat
*)
Output:
{8, 12, 20, 36, 44, 60, 84, 116, 140, 156, 204, 260, 380, 420, 660, 924}

Arturo

found: select 6..998 => even?

loop 1..497 'l ->
    loop 1..l 'w [
        lw: l * w
        if lw >= 498 -> break
        loop 1..w 'h [
            sa: 2 * (lw + (w*h) + h*l)
            (sa < 1000)? -> 'found -- sa
                         -> break
        ]
    ]

print found
Output:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

BASIC

Rosetta Code problem: https://rosettacode.org/wiki/O%27Halloran_numbers

by Jjuanhdez, 02/2023

BASIC256

Translation of: FreeBASIC
maxArea = 1000
halfMaxArea = maxArea/2
dim T[halfMaxArea]       #table of half areas
for i = 0 to halfMaxArea-1
	T[i] = True          #assume all are O'kalloran numbers
next i
for l = 1 to maxArea
	for w = 1 to halfMaxArea
		for h = 1 to halfMaxArea
			suma = l*w + l*h + w*h
			if suma < halfMaxArea then T[suma] = False  #not an O'kalloran number
		next h
	next w
next l

print "All known O'Halloran numbers:"
for l = 6/2 to halfMaxArea-1
	if T[l] then print int(l*2); " ";
next l
Output:
All known O'Halloran numbers:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Chipmunk Basic

Translation of: BASIC256
Works with: Chipmunk Basic version 3.6.4
Works with: QBasic
100 cls
110 maxarea = 1000
120 halfmaxarea = maxarea/2
130 dim t(halfmaxarea)'table of half areas
140 for i = 0 to halfmaxarea-1
150  t(i) = 1 'assume all are O'kalloran numbers
160 next i
170 for l = 1 to maxarea
180  for w = 1 to halfmaxarea
190   for h = 1 to halfmaxarea
200    suma = l*w+l*h+w*h
210    if suma < halfmaxarea then t(suma) = 0 'not an O'kalloran number
220   next h
230  next w
240 next l
250 print "All known O'Halloran numbers:"
260 print "[ ";
270 for l = 6/2 to halfmaxarea-1
280  if t(l) then print int(l*2);" ";
290 next l
300 print chr$(8);"]"
310 end

FreeBASIC

Const maxArea = 1000, halfMaxArea = maxArea/2
Dim As Integer i, l, w, h, suma
Dim As Boolean T(halfMaxArea)       'table of half areas

For i = 0 To halfMaxArea-1
    T(i) = True                     'assume all are O'kalloran numbers
Next i

For l = 1 To maxArea
    For w = 1 To halfMaxArea
        For h = 1 To halfMaxArea
            suma = l*w + l*h + w*h
            If suma < halfMaxArea Then T(suma) = False  'not an O'kalloran number
        Next h, w, l

Print "All known O'Halloran numbers:"
Print "[";
For l = 6/2 To halfMaxArea-1
    If T(l) Then Print l*2; ",";
Next l
Print Chr(8); " ]"
Sleep
Output:
All known O'Halloran numbers:
[ 8, 12, 20, 36, 44, 60, 84, 116, 140, 156, 204, 260, 380, 420, 660, 924 ]

QBasic

Works with: QBasic version 1.1
Works with: QuickBasic version 4.5

The Chipmunk Basic solution works without any changes.

True BASIC

Translation of: BASIC256
LET maxarea = 1000
LET halfmaxarea = maxarea/2
DIM t(1)
MAT REDIM t(0 TO halfmaxarea)     !Table of half areas
FOR i = 0 TO halfmaxarea-1
    LET t(i) = 1                  !assume all are O'kalloran numbers
NEXT i
FOR l = 1 TO maxarea
    FOR w = 1 TO halfmaxarea
        FOR h = 1 TO halfmaxarea
            LET suma = l*w+l*h+w*h
            IF suma < halfmaxarea THEN LET t(suma) = 0     !not an O'kalloran number
        NEXT h
    NEXT w
NEXT l
PRINT "All known O'Halloran numbers:"
FOR l = 6/2 TO halfmaxarea-1
    IF t(l) = 1 THEN PRINT INT(l*2);" ";
NEXT l
END

Yabasic

Translation of: FreeBASIC
maxArea = 1000
halfMaxArea = maxArea/2
dim T(halfMaxArea)             //table of half areas
for i = 0 to halfMaxArea-1
    T(i) = True                //assume all are O'kalloran numbers
next i
for l = 1 to maxArea
    for w = 1 to halfMaxArea
        for h = 1 to halfMaxArea
            suma = l*w + l*h + w*h
            if suma < halfMaxArea  T(suma) = False  //not an O'kalloran number
        next h
    next w
next l

print "All known O'Halloran numbers:"
print "[";
for l = 6/2 to halfMaxArea-1
    if T(l)  print l*2, ",";
next l
print chr$(8), "]"
Output:
All known O'Halloran numbers:
[8,12,20,36,44,60,84,116,140,156,204,260,380,420,660,924]

C

Translation of: Wren

More or less.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main() {
    bool *found = calloc(1000, sizeof(bool)); // all false initially
    int i, l, w, h, lw, sa;
    for (l = 1; l < 498; ++l) {
        for (w = 1; w <= l; ++w) {
            lw = l * w;
            if (lw >= 498) break;
            for (h = 1; h <= w; ++h) {
                sa = (lw + w*h + h*l) * 2;
                if (sa < 1000) found[sa] = true;
            }
        }
    }
    printf("All known O'Halloran numbers:\n[");
    for (i = 6; i < 1000; i += 2) {
        if (!found[i]) printf("%d, ", i);
    }
    printf("\b\b]\n");
    free(found);
    return 0;
}
Output:
All known O'Halloran numbers:
[8, 12, 20, 36, 44, 60, 84, 116, 140, 156, 204, 260, 380, 420, 660, 924] 


C#

using System;
using System.Linq;

class OHalloranNumbers
{
    static void Main(string[] args)
    {
        int maximumArea = 1000;
        int halfMaximumArea = maximumArea / 2;

        bool[] ohalloranNumbers = Enumerable.Repeat(true, halfMaximumArea).ToArray();

        for (int length = 1; length < maximumArea; length++)
        {
            for (int width = 1; width < halfMaximumArea; width++)
            {
                for (int height = 1; height < halfMaximumArea; height++)
                {
                    int halfArea = length * width + length * height + width * height;
                    if (halfArea < halfMaximumArea)
                    {
                        ohalloranNumbers[halfArea] = false;
                    }
                }
            }
        }

        Console.WriteLine("Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:");
        for (int i = 3; i < halfMaximumArea; i++)
        {
            if (ohalloranNumbers[i])
            {
                Console.Write(i * 2 + " ");
            }
        }
        Console.WriteLine();
    }
}
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 


C++

#include <cstdint>
#include <iostream>
#include <vector>

int main() {
	const uint32_t maximum_area = 1'000;
	const uint32_t half_maximum_area = maximum_area / 2;

	std::vector<uint32_t> ohalloran_numbers(half_maximum_area, true);

	for ( uint32_t length = 1; length < maximum_area; ++length ) {
		for ( uint32_t width = 1; width < half_maximum_area; ++width ) {
			for ( uint32_t height = 1; height < half_maximum_area; ++height ) {
				uint32_t half_area = length * width + length * height + width * height;
				if ( half_area < half_maximum_area ) {
					ohalloran_numbers[half_area] = false;
				}
			}
		}
	}

	std::cout << "Values larger than 6 and less than 1_000 which cannot be the surface area of a cuboid:"
              << std::endl;
	for ( uint32_t i = 3; i < half_maximum_area; ++i ) {
		if ( ohalloran_numbers[i] ) {
			std::cout << i * 2 << " ";
		}
	}
	std::cout << std::endl;
}
Output:
Values larger than 6 and less than 1_000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Dart

Translation of: Scala
import "dart:io";

void main() {
  const int maximumArea = 1000;
  int halfMaximumArea = maximumArea ~/ 2;

  List<bool> ohalloranNumbers = List<bool>.filled(halfMaximumArea, true);

  for (int length = 1; length < maximumArea; length++) {
    for (int width = 1; width < halfMaximumArea; width++) {
      for (int height = 1; height < halfMaximumArea; height++) {
        int halfArea = length * width + length * height + width * height;
        if (halfArea < halfMaximumArea) {
          ohalloranNumbers[halfArea] = false;
        }
      }
    }
  }

  print("Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:");
  for (int i = 3; i < halfMaximumArea; i++) {
    if (ohalloranNumbers[i]) {
      stdout.write('${i * 2} ');
    }
  }
}
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Delphi

Works with: Delphi version 6.0


procedure ShowOHalloranNumbers(Memo: TMemo);
var L, W, H: integer;
var CubeArea, I, Cnt: integer;
const Limit = 1000;
const Limit2 = Limit div 2;
const Limit4 = Limit div 4;
var ValidOH: array [0..Limit2] of boolean;
var S: string;
begin
{Since we are using CuboidArea/2, use half the space }
for I:= 0 to Limit2-1 do ValidOH[I]:= true;
for L:= 1 to Limit4 do
 for W:= 1 to L do
  for H:= 1 to L do
	begin
	{Calculate 1/2 Cuboid value}
	CubeArea:=L * W + L * H + W * H;
	{Make sure number doesn't overrun array}
	if CubeArea>=Length(ValidOH) then continue;
	{Mark it as not an OHalloran number}
	ValidOH[CubeArea]:= false;
	end;
S:=''; Cnt:=0;
{Since we are using half the space}
{everything has to be doubled}
for I:=2 * 3 to Limit2-1 do
 if ValidOH[I] then
	begin
	Inc(Cnt);
	S:=S+Format('%8D',[I*2]);
	If (Cnt mod 5)=0 then S:=S+CRLF;
	end;

Memo.Lines.Add(S);
Memo.Lines.Add('Count='+IntToStr(Cnt));
end;
Output:
      12      20      36      44      60
      84     116     140     156     204
     260     380     420     660     924

Count=15
Elapsed Time: 6.353 ms.


EasyLang

Translation of: C
len found[] 1000
for l = 1 to 497
   for w = 1 to l
      lw = l * w
      if lw >= 498
         break 1
      .
      for h = 1 to w
         sa = (lw + w * h + h * l) * 2
         if sa <= 1000
            found[sa] = 1
         .
      .
   .
.
for i = 6 step 2 to 998
   if found[i] = 0
      write i & " "
   .
.

Fortran

Translation of: Julia
program ohalloran_numbers
    implicit none
    integer, parameter :: max_area = 1000
    integer :: half_max, i, j, k, area
    logical, dimension(max_area) :: areas
    half_max = max_area / 2
    
    ! Initialize areas with .TRUE.
    areas = .TRUE.
    
    do i = 1, max_area
        do j = 1, half_max
            if (i * j > half_max) exit
            do k = 1, half_max
                area = 2 * (i * j + i * k + j * k)
                if (area > max_area) exit
                areas(area) = .FALSE. ! Mark as not an O'Halloran number
            end do
        end do
    end do
    
    ! Print the O'Halloran numbers
    print *, "Even surface areas < NOT ", max_area, " achievable by any regular integer-valued cuboid:"
    do i = 1, max_area
    	if (mod(i, 2) == 0 .AND. areas(i)) then
        	write(*,'(I4,1X)', advance='no') i
    	endif
     end do
     print *, "" ! To add a final newline after the list
end program ohalloran_numbers
Output:
 Even surface areas < NOT         1000  achievable by any regular integer-valued cuboid:
   2    4    8   12   20   36   44   60   84  116  140  156  204  260  380  420  660  924  


FutureBasic

 
_maxArea = 1000
_halfMaxArea = 500

NSUInteger i, l, w, h, sum
BOOL table( _halfMaxArea )

// Populate boolean table
for i = 0 to _halfMaxArea - 1
  table( i ) = YES
next

for l = 1 to _maxArea
  for w = 1 to _maxArea
    for h = 1 to _halfMaxArea
      sum = l * w + l * h + w * h
      if sum < _halfMaxArea then table( sum ) = NO
    next
  next
next

printf @"All known O'Halloran numbers:"
for l = 6/2 to _halfMaxArea - 1
  if table( l ) then print l * 2,
next
print chr$(8),

HandleEvents
Output:
All known O'Halloran numbers:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Go

Translation of: C
package main

import "fmt"

func main() {
    found := make([]bool, 1000) // all false initially
    for l := 1; l < 498; l++ {
        for w := 1; w <= l; w++ {
            lw := l * w
            if lw >= 498 {
                break
            }
            for h := 1; h <= w; h++ {
                sa := (lw + w*h + h*l) * 2
                if sa < 1000 {
                    found[sa] = true
                }
            }
        }
    }
    fmt.Printf("All known O'Halloran numbers:\n[")
    for i := 6; i < 1000; i += 2 {
        if !found[i] {
            fmt.Printf("%d, ", i)
        }
    }
    fmt.Printf("\b\b]\n")
}
Output:
All known O'Halloran numbers:
[8, 12, 20, 36, 44, 60, 84, 116, 140, 156, 204, 260, 380, 420, 660, 924] 

J

   require'stats'
   2*(3}.i.501)-.+/1 */\.(|:3 comb 42)-i:1
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

Here, we use combinations with repetitions to generate the various relevant cuboid side lengths. Then we multiply all three pairs of these side length combinations and sum the pairs. Then we remove these sums from the sequence 3..500, and finally we multiply the remaining 16 values by 2.

Java

 
import java.util.Arrays;

public final class OHalloranNumbers {

	public static void main(String[] args) {
		final int maximumArea = 1_000;
		final int halfMaximumArea = maximumArea / 2;
		
		boolean[] ohalloranNumbers = new boolean[halfMaximumArea];
		Arrays.fill(ohalloranNumbers, true);
				
		for ( int length = 1; length < maximumArea; length++ ) {
		    for ( int width = 1; width < halfMaximumArea; width++ ) {
		        for ( int height = 1; height < halfMaximumArea; height++ ) {
		            int halfArea = length * width + length * height + width * height;
		            if ( halfArea < halfMaximumArea ) {
		                ohalloranNumbers[halfArea] = false;
		            }
		        }
		    }
		}
		
		System.out.println("Values larger than 6 and less tha 1_000 which cannot be the surface area of a cuboid:");
		for ( int i = 3; i < halfMaximumArea; i++ ) {
		    if ( ohalloranNumbers[i] ) {
		        System.out.print(i * 2 + " ");
		    }
		}
		System.out.println();
	}

}
Output:
Values larger than 6 and less than 1_000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

JavaScript

Translation of: ALGOL 68
// find O'Halloran numbers - numbers that cannot be the surface area of
//                           a cuboid with integer dimensions
'use strict'
const maxArea     = 1000
const halfMaxArea = Math.trunc( maxArea / 2 )
let   list        = ""
for( let n = 8; n <= maxArea; n += 2 )
{
    let oHalloran = true
    for( let l = 1; l <= halfMaxArea && oHalloran; l ++ )
    {
        for( let b = l; b <= halfMaxArea; b ++ )
        {
            const lb = l * b
            if( lb >= n || ! oHalloran )break
            for( let h = b; h <= halfMaxArea; h ++ )
            {
                const bh  = b * h, lh = l * h
                const sum = 2 * ( lb + bh + lh )
                oHalloran = sum != n 
                if( sum > n || ! oHalloran )break;
            }
        }
    }
    if( oHalloran )
    {
        list = list + " " + n
    }
}
console.log( list )
Output:
 8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

jq

Works with: jq

Also works with jaq and with gojq, the Go implementation of jq

# Emit a stream of possible cuboid areas less than or equal to the specified limit, 
# $maxarea, which should be an even integer.
def cuboid_areas(maxarea):
  maxarea as $maxarea
  # min area per face is 1 so if total area is $maxarea, the max dimension is ($maxarea-4)/2
  | ($maxarea/2) as $halfmax
  | ($halfmax - 2) as $max
  | foreach range(1; 1+$max) as $i (null;
      label $loopj
      # By symmetry, we can assume i <= j <= k
      | foreach range($i; 1+$max) as $j (.;
          ($i*$j) as $ij
          | if $ij + 2 > $halfmax then break $loopj else . end
	  | label $loopk
          | foreach range($j; 1+$max) as $k (.;
	      ($ij + $i*$k + $j*$k) as $total
              | if $total > $halfmax then break $loopk
	        else 2 * $total
		end) ) );

1000 as $n
| "Even integers greater than 6 but less than \($n) that cannot be cuboid surface areas:",
  [range(6;$n;2)] - [cuboid_areas($n-2)]
Even integers greater than 6 but less than 1000 that cannot be cuboid surface areas:
[8,12,20,36,44,60,84,116,140,156,204,260,380,420,660,924]

Julia

""" Rosetta code task: rosettacode.org/wiki/O%27Halloran_numbers """

const max_area, half_max = 1000, 500
const areas = trues(max_area)

areas[1:2:max_area] .= false

for i in 1:max_area
    for j in 1:half_max
        i * j > half_max && break
        for k in 1:half_max
            area = 2 * (i * j + i * k + j * k)
            area > max_area && break
            areas[area] = false
        end
    end
end

println("Even surface areas < $max_area NOT achievable by any regular integer-valued cuboid:\n",
    [n for n in eachindex(areas) if areas[n]])
Output:
Even surface areas < 1000 NOT achievable by any regular integer-valued cuboid:
[2, 4, 8, 12, 20, 36, 44, 60, 84, 116, 140, 156, 204, 260, 380, 420, 660, 924]

Kotlin

Translation of: Scala
object OHalloranNumbers {

    @JvmStatic
    fun main(args: Array<String>) {
        val maximumArea = 1_000
        val halfMaximumArea = maximumArea / 2

        var ohalloranNumbers = BooleanArray(halfMaximumArea) { true }

        for (length in 1 until maximumArea) {
            for (width in 1 until halfMaximumArea) {
                for (height in 1 until halfMaximumArea) {
                    val halfArea = length * width + length * height + width * height
                    if (halfArea < halfMaximumArea) {
                        ohalloranNumbers[halfArea] = false
                    }
                }
            }
        }

        println("Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:")
        for (i in 3 until halfMaximumArea) {
            if (ohalloranNumbers[i]) {
                print("${i * 2} ")
            }
        }
        println()
    }
}

fun main() {
    OHalloranNumbers.main(arrayOf())
}
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 


Lua

function calculateOHalloranNumbers(maximumArea)
    local halfMaximumArea = maximumArea / 2
    local ohalloranNumbers = {}

    -- Initialize the ohalloranNumbers table with all true values
    for i = 1, halfMaximumArea do
        ohalloranNumbers[i] = true
    end

    -- Calculate surface areas of possible cuboids and exclude them
    for length = 1, maximumArea - 1 do
        for width = 1, halfMaximumArea - 1 do
            for height = width, halfMaximumArea - 1 do
                local halfArea = length * width + length * height + width * height
                if halfArea < halfMaximumArea then
                    ohalloranNumbers[halfArea] = false
                else
                    break
                end
            end
            if length * width * 2 >= halfMaximumArea then
                break
            end
        end
    end

    -- Print out the O'Halloran numbers
    print("Values larger than 6 and less than " .. maximumArea .. " which cannot be the surface area of a cuboid:")
    for i = 3, halfMaximumArea-1 do
        if ohalloranNumbers[i] then
            io.write((2 * (i)) .. " ")
        end
    end
    print()
end

-- Call the function with the maximum area of 1000
calculateOHalloranNumbers(1000)
Output:
Values larger than 6 and less than 1000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 


Mathematica/Wolfram Language

(* Rosetta code task: rosettacode.org/wiki/O%27Halloran_numbers *)

maxArea = 1000;
halfMax = 500;
areas = Table[True, {maxArea}];

areas[[1 ;; maxArea ;; 2]] = False;

For[i = 1, i <= maxArea, i++,
  For[j = 1, j <= halfMax,
    j++, If[i*j > halfMax, Break[]];
    For[k = 1, k <= halfMax,
      k++, area = 2 (i*j + i*k + j*k);
      If[area > maxArea, Break[]];
      areas[[area]] = False;
    ];
  ];
];

Print["Even surface areas < ", maxArea, " NOT achievable by any regular integer-valued cuboid:\n",
  Select[Range[maxArea], areas[[#]] &]]
Output:
Even surface areas < 1000 NOT achievable by any regular integer-valued cuboid:
{2, 4, 8, 12, 20, 36, 44, 60, 84, 116, 140, 156, 204, 260, 380, 420, 660, 924}

MATLAB/Octave

Translation of: Julia
max_area = 1000;
half_max = max_area / 2;
areas = ones(1, max_area); % Initialize areas with 1's

for i = 1:max_area
    for j = 1:half_max
        if (i * j > half_max)
            break;
        endif
        for k = 1:half_max
            area = 2 * (i * j + i * k + j * k);
            if (area > max_area)
                break;
            endif
            areas(area) = 0; % Mark as not an O'Halloran number
        endfor
    endfor
endfor

% Print the O'Halloran numbers
printf("Even surface areas < NOT %d achievable by any regular integer-valued cuboid:\n", max_area);
for n = 1:max_area/2
    if (areas(2*n))
        printf("%d ", 2*n);
    endif
endfor
printf("\n");
Output:
Even surface areas < NOT 1000 achievable by any regular integer-valued cuboid:
2 4 8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Nim

import std/algorithm

const
  M = 1000      # Maximum area.
  N = M div 2   # Maximum half area.

var isOHalloran: array[3..N, bool]
isOHalloran.fill(true)

for length in 1..N:
  for width in 1..length:
    let plw = length * width
    if plw > N: break
    let slw = length + width
    for height in 1..width:
      let halfArea = plw + height * slw
      if halfArea > N: break
      isOHalloran[halfArea] = false

echo "All known O'Halloran numbers:"
for n in 3..N:
  if isOHalloran[n]:
    stdout.write 2 * n, ' '
echo()
Output:
All known O'Halloran numbers:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

OCaml

let maximum_area = 1000;;
let half_maximum_area = maximum_area / 2;;

let ohalloran_numbers = Array.make half_maximum_area true;;

for length = 1 to maximum_area - 1 do
  for width = 1 to half_maximum_area - 1 do
    for height = 1 to half_maximum_area - 1 do
      let half_area = length * width + length * height + width * height in
      if half_area < half_maximum_area then
        ohalloran_numbers.(half_area) <- false
    done;
  done;
done;;

Printf.printf "Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:\n";
for i = 3 to half_maximum_area - 1 do
  if ohalloran_numbers.(i) then
    Printf.printf "%d " (i * 2)
done;
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

PARI/GP

Translation of: Julia
{
    max_area = 1000;
    half_max = max_area / 2;
    areas = vector(max_area, i, 1); /* Initialize areas with 1's */

    for (i = 1, max_area,
        for (j = 1, half_max,
            if (i * j > half_max, break);
            for (k = 1, half_max,
                area = 2 * (i * j + i * k + j * k);
                if (area > max_area, break);
                areas[area] = 0; /* Mark as not an O'Halloran number */
            )
        )
    );

    /* Print the O'Halloran numbers */
    print("Even surface areas < NOT ", Str(max_area) , " achievable by any regular integer-valued cuboid:");
    for (n = 2/2, max_area/2,
        if (areas[2*n], print1(2*n, " "));
    );
}
Output:
Even surface areas < NOT 1000 achievable by any regular integer-valued cuboid:
2 4 8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 



Perl

use v5.36;
my @A;
my $threshold = 10_000; # redonkulous overkill

for my $x (1..$threshold) {
    X: for my $y (1..$x) {
        last X if $x*$y > $threshold;
        Y: for my $z (1..$y) {
           last Y if (my $area = 2 * ($x*$y + $y*$z + $z*$x)) > $threshold;
           $A[$area] = "$x,$y,$z";
        }
    }

say 'Even integer surface areas NOT achievable by any regular, integer dimensioned cuboid';
for (0..$#A) {
    print "$_ " if $_ < $threshold and $_ > 6 and 0 == $_ % 2 and not $A[$_];
}
Output:
Even integer surface areas NOT achievable by any regular, integer dimensioned cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

Phix

Since we are going to check {1,1,2}, there is no point checking {1,2,1} or {2,1,1} etc.

with javascript_semantics
constant max_area = 1000, half_max = max_area/2
sequence areas = repeat(0,5)&tagset(max_area,6)

for x=1 to max_area do
    if odd(x) then areas[x] = 0 end if
    for y=x to floor(half_max/x) do
        for z=y to half_max do
            atom area = 2 * (x * y + x * z + y * z)
            if area > max_area then exit end if
            areas[area] = 0
        end for
    end for
end for

printf(1,"Even surface areas < %d NOT achievable by any regular integer-valued cuboid:\n%s\n",
         {max_area,join(filter(areas,"!=",0),fmt:="%d")})
Output:

You can also set max_area to 1,000,000 and get no more results.

Even surface areas < 1000 NOT achievable by any regular integer-valued cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

PHP

Translation of: Scala
<?php

function main() {
    $maximumArea = 1000;
    $halfMaximumArea = $maximumArea / 2;

    $ohalloranNumbers = array_fill(0, $halfMaximumArea, true);

    for ($length = 1; $length < $maximumArea; $length++) {
        for ($width = 1; $width < $halfMaximumArea; $width++) {
            for ($height = 1; $height < $halfMaximumArea; $height++) {
                $halfArea = $length * $width + $length * $height + $width * $height;
                
                if ($halfArea < $halfMaximumArea) {
                    $ohalloranNumbers[$halfArea] = false;
                }
            }
        }
    }

    echo "Values larger than 6 and less than $maximumArea which cannot be the surface area of a cuboid:\n";
    for ($i = 3; $i < $halfMaximumArea; $i++) {
        if ($ohalloranNumbers[$i]) {
            echo ($i * 2) . " ";
        }
    }
    echo "\n";
}

main();

?>
Output:
Values larger than 6 and less than 1000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Python

Translation of: FreeBASIC
#!/usr/bin/python

maxArea = 1000
halfMaxArea = 500
T = []                           #table of half areas
for i in range(halfMaxArea):
    T.append(True)               #assume all are O'kalloran numbers

for l in range(1,maxArea):
    for w in range(1, halfMaxArea):
        for h in range(1, halfMaxArea):
            suma = l*w + l*h + w*h
            if suma < halfMaxArea:
                T[suma] = False  #not an O'kalloran number

print("All known O'Halloran numbers:")
for l in range(3,halfMaxArea):
    if T[l]:
        print(l*2, end=" ");
Output:
All known O'Halloran numbers:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

PROMAL

;;; find O'Halloran numbers - numbers that cannot be the surface area of
;;;                           a cuboid with integer dimensions
PROGRAM OHalloran
INCLUDE LIBRARY

CON WORD maxArea = 1000
WORD count
WORD halfMaxArea
WORD n
WORD l
WORD b
WORD h
WORD lb
WORD lh
WORD bh
WORD sum
BYTE isOHalloran
BEGIN
count = 0
halfMaxArea = maxArea / 2
n = 8
WHILE n <= maxArea
  isOHalloran = 1
  l = 1
  REPEAT
    b  = l
    lb = l * b
    REPEAT
      h = b
      REPEAT
        bh  = b * h
        lh  = l * h
        sum = 2 * ( lb + ( h * ( b + l ) ) )
        IF sum = n
          isOHalloran = 0
        h = h + 1
      UNTIL h > halfMaxArea OR sum > n OR NOT isOHalloran
      b  = b + 1
      lb = l * b
    UNTIL b > halfMaxArea OR lb >= n OR NOT isOHalloran
    l = l + 1
  UNTIL l > halfMaxArea OR NOT isOHalloran
  IF isOHalloran
    OUTPUT " #W", n
    count = count + 1
  n = n + 2
END
Output:
 8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

R

Translation of: Julia
max_area <- 1000
half_max <- max_area / 2
areas <- rep(1, max_area) # Initialize areas with 1's

for (i in 1:max_area) {
  for (j in 1:half_max) {
    if (i * j > half_max) {
      break
    }
    for (k in 1:half_max) {
      area <- 2 * (i * j + i * k + j * k)
      if (area > max_area) {
        break
      }
      areas[area] <- 0 # Mark as not an O'Halloran number
    }
  }
}

# Print the O'Halloran numbers
cat("Even surface areas < NOT", max_area, "achievable by any regular integer-valued cuboid:\n")
for (n in 3:(max_area/2)) {
  if (areas[2*n] == 1) {
    cat(2*n, " ")
  }
}
cat("\n") # To ensure the output ends with a newline
Output:
Even surface areas < NOT 1000 achievable by any regular integer-valued cuboid:
8  12  20  36  44  60  84  116  140  156  204  260  380  420  660  924  


Racket

Translation of: Scala
#lang racket

(define (main)
  (let ([maximum-area 1000]
        [ohalloran-numbers (make-hash)])
    ;; Initialize the hash table
    (for ([i (in-range (quotient maximum-area 2))])
      (hash-set! ohalloran-numbers i #t))

    ;; Calculate cuboid surface areas and update the hash table
    (for* ([length (in-range 1 maximum-area)]
           [width (in-range 1 (quotient maximum-area 2))]
           [height (in-range 1 (quotient maximum-area 2))])
      (let* ([half-area (+ (* length width) (* length height) (* width height))])
        (when (< half-area (quotient maximum-area 2))
          (hash-set! ohalloran-numbers half-area #f))))

    ;; Print the results
    (printf "Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:\n")
    (for ([i (in-range 3 (quotient maximum-area 2))])
      (when (hash-ref ohalloran-numbers i)
        (printf "~a " (* i 2))))
    (printf "\n")))

(main)
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 


Raku

my @Area;

my $threshold = 1000; # a little overboard to make sure we get them all

for 1..$threshold -> $x {
    for 1..$x -> $y {
        last if $x × $y > $threshold;
        for 1..$y -> $z {
           push @Area[my $area = ($x × $y + $y × $z + $z × $x) × 2], "$x,$y,$z";
           last if $area > $threshold;
        }
    }
}

say "Even integer surface areas NOT achievable by any regular, integer dimensioned cuboid:\n" ~
   @Area[^$threshold].kv.grep( { $^key > 6 and $key %% 2 and !$^value } )»[0];
Output:
Even integer surface areas NOT achievable by any regular, integer dimensioned cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924

Ruby

class OHalloranNumbers
  def self.main
    maximum_area = 1_000
    half_maximum_area = maximum_area / 2

    ohalloran_numbers = Array.new(half_maximum_area, true)

    (1...maximum_area).each do |length|
      (1...half_maximum_area).each do |width|
        (1...half_maximum_area).each do |height|
          half_area = length * width + length * height + width * height
          ohalloran_numbers[half_area] = false if half_area < half_maximum_area
        end
      end
    end

    puts "Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:"
    (3...half_maximum_area).each do |i|
      print "#{i * 2} " if ohalloran_numbers[i]
    end
    puts
  end
end

OHalloranNumbers.main
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 


Rust

Translation of: C++
fn main() {
    const MAXIMUM_AREA: u32 = 1_000;
    const HALF_MAXIMUM_AREA: u32 = MAXIMUM_AREA / 2;

    let mut ohalloran_numbers = vec![true; HALF_MAXIMUM_AREA as usize];

    for length in 1..MAXIMUM_AREA {
        for width in 1..HALF_MAXIMUM_AREA {
            for height in 1..HALF_MAXIMUM_AREA {
                let half_area = length * width + length * height + width * height;
                if half_area < HALF_MAXIMUM_AREA {
                    ohalloran_numbers[half_area as usize] = false;
                }
            }
        }
    }

    println!("Values larger than 6 and less than 1_000 which cannot be the surface area of a cuboid:");
    for i in 3..HALF_MAXIMUM_AREA {
        if ohalloran_numbers[i as usize] {
            print!("{} ", i * 2);
        }
    }
    println!();
}
Output:
Values larger than 6 and less than 1_000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 


RPL

Translation of: JavaScript
Works with: HP version 48
« 1000 DUP 2 / FLOOR 1 → maxarea halfmax ohalloran
  « { }
    8 maxarea FOR n
       1 ohalloran SF  
       WHILE DUP halfmax ≤ ohalloran FS? AND REPEAT
          1 halfmax FOR b
             DUP b *
             IF DUP n ≥ ohalloran FC? OR THEN DROP halfmax 'b' STO
             ELSE 
                b halfmax FOR h
                   OVER h * OVER + h b * + DUP +
                   IF DUP n == THEN ohalloran CF END
                   IF n > ohalloran FC? OR THEN halfmax 'h' STO END
                NEXT DROP 
             END 
          NEXT 
          1 +
       END DROP 
       IF ohalloran FS? THEN n + END
    2 STEP           
» » 'OHALL' STO
Output:
1: { 8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 }

Scala

Translation of: Java
object OHalloranNumbers {

  def main(args: Array[String]): Unit = {
    val maximumArea = 1_000
    val halfMaximumArea = maximumArea / 2

    var ohalloranNumbers = Array.fill[Boolean](halfMaximumArea)(true)

    for {
      length <- 1 until maximumArea
      width <- 1 until halfMaximumArea
      height <- 1 until halfMaximumArea
    } {
      val halfArea = length * width + length * height + width * height
      if (halfArea < halfMaximumArea) {
        ohalloranNumbers(halfArea) = false
      }
    }

    println("Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:")
    for {
      i <- 3 until halfMaximumArea
      if ohalloranNumbers(i)
    } {
      print(i * 2 + " ")
    }
    println()
  }
}
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Swift

Translation of: Scala
import Foundation

func main() {
    let maximumArea = 1_000
    let halfMaximumArea = maximumArea / 2

    var ohalloranNumbers = Array(repeating: true, count: halfMaximumArea)

    for length in 1..<maximumArea {
        for width in 1..<halfMaximumArea {
            for height in 1..<halfMaximumArea {
                let halfArea = length * width + length * height + width * height
                if halfArea < halfMaximumArea {
                    ohalloranNumbers[halfArea] = false
                }
            }
        }
    }

    print("Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:")
    for i in 3..<halfMaximumArea where ohalloranNumbers[i] {
        print(i * 2, terminator: " ")
    }
    print()
}

// Running the main function
main()
Output:
Values larger than 6 and less than 1,000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 

Tcl

proc calculateOHalloranNumbers { maximumArea } {
    set halfMaximumArea [expr {$maximumArea / 2}]
    set ohalloranNumbers [list]
    
    # Initialize the ohalloranNumbers list with all true values
    for {set i 0} {$i < $halfMaximumArea} {incr i} {
        lappend ohalloranNumbers true
    }

    # Calculate surface areas of possible cuboids and exclude them
    for {set length 1} {$length < $maximumArea} {incr length} {
        for {set width 1} {$width < $halfMaximumArea} {incr width} {
            for {set height $width} {$height < $halfMaximumArea} {incr height} {
                set halfArea [expr {$length * $width + $length * $height + $width * $height}]
                if {$halfArea < $halfMaximumArea} {
                    lset ohalloranNumbers $halfArea false
                } else {
                    break
                }
            }
            if { $length * $width * 2 >= $halfMaximumArea } {
                break
            }
        }
    }

    # Print out the O'Halloran numbers
    puts "Values larger than 6 and less than $maximumArea which cannot be the surface area of a cuboid:"
    for {set i 3} {$i < $halfMaximumArea} {incr i} {
        if {[lindex $ohalloranNumbers $i]} {
            puts -nonewline "[expr {2 * $i}] "
        }
    }
    puts ""
}

# Call the procedure with the maximum area of 1000
calculateOHalloranNumbers 1000
Output:
Values larger than 6 and less than 1000 which cannot be the surface area of a cuboid:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924 


Wren

import "./seq" for Lst

var found = []
for (l in 1..497) {
    for (w in 1..l) {
        var lw = l * w
        if (lw >= 498) break
        for (h in 1..w) {
            var sa = (lw + w*h + h*l) * 2
            if (sa < 1000) found.add(sa) else break
        }
    }
}
var allEven = (6..998).where { |i| i%2 == 0 }.toList
System.print("All known O'Halloran numbers:")
System.print(Lst.except(allEven, found))
Output:
All known O'Halloran numbers:
[8, 12, 20, 36, 44, 60, 84, 116, 140, 156, 204, 260, 380, 420, 660, 924]

XPL0

int  L, W, H, HA, I;
char T(1000/2);                 \table of half areas
[for I:= 0 to 1000/2-1 do
        T(I):= true;            \assume all are O'Halloran numbers
for L:= 1 to 250 do
    for W:= 1 to 250/L do
        for H:= 1 to 250/L do
            [HA:= L*W + L*H + W*H;
            if HA < 500 then    \not an O'Halloran number
                T(HA):= false;
            ];
for I:= 6/2 to 1000/2-1 do
    if T(I) then
        [IntOut(0, I*2);  ChOut(0, ^ )];
]
Output:
8 12 20 36 44 60 84 116 140 156 204 260 380 420 660 924