package main

import (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"time"

	termbox "github.com/nsf/termbox-go"
)

func main() {
	rand.Seed(time.Now().UnixNano())
	score, err := playSnake()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Final score:", score)
}

type snake struct {
	body          []position // tail to head positions of the snake
	heading       direction
	width, height int
	cells         []termbox.Cell
}

type position struct {
	X int
	Y int
}

type direction int

const (
	North direction = iota
	East
	South
	West
)

func (p position) next(d direction) position {
	switch d {
	case North:
		p.Y--
	case East:
		p.X++
	case South:
		p.Y++
	case West:
		p.X--
	}
	return p
}

func playSnake() (int, error) {
	err := termbox.Init()
	if err != nil {
		return 0, err
	}
	defer termbox.Close()

	termbox.Clear(fg, bg)
	termbox.HideCursor()
	s := &snake{
		// It would be more efficient to use a circular
		// buffer instead of a plain slice for s.body.
		body:  make([]position, 0, 32),
		cells: termbox.CellBuffer(),
	}
	s.width, s.height = termbox.Size()
	s.drawBorder()
	s.startSnake()
	s.placeFood()
	s.flush()

	moveCh, errCh := s.startEventLoop()
	const delay = 125 * time.Millisecond
	for t := time.NewTimer(delay); ; t.Reset(delay) {
		var move direction
		select {
		case err = <-errCh:
			return len(s.body), err
		case move = <-moveCh:
			if !t.Stop() {
				<-t.C // handles race between moveCh and t.C
			}
		case <-t.C:
			move = s.heading
		}
		if s.doMove(move) {
			time.Sleep(1 * time.Second)
			break
		}
	}

	return len(s.body), err
}

func (s *snake) startEventLoop() (<-chan direction, <-chan error) {
	moveCh := make(chan direction)
	errCh := make(chan error, 1)
	go func() {
		defer close(errCh)
		for {
			switch ev := termbox.PollEvent(); ev.Type {
			case termbox.EventKey:
				switch ev.Ch { // WSAD and HJKL movement
				case 'w', 'W', 'k', 'K':
					moveCh <- North
				case 'a', 'A', 'h', 'H':
					moveCh <- West
				case 's', 'S', 'j', 'J':
					moveCh <- South
				case 'd', 'D', 'l', 'L':
					moveCh <- East
				case 0:
					switch ev.Key { // Cursor key movement
					case termbox.KeyArrowUp:
						moveCh <- North
					case termbox.KeyArrowDown:
						moveCh <- South
					case termbox.KeyArrowLeft:
						moveCh <- West
					case termbox.KeyArrowRight:
						moveCh <- East
					case termbox.KeyEsc: // Quit
						return
					}
				}
			case termbox.EventResize:
				// TODO
				errCh <- errors.New("terminal resizing unsupported")
				return
			case termbox.EventError:
				errCh <- ev.Err
				return
			case termbox.EventInterrupt:
				return
			}
		}
	}()
	return moveCh, errCh
}

func (s *snake) flush() {
	termbox.Flush()
	s.cells = termbox.CellBuffer()
}

func (s *snake) getCellRune(p position) rune {
	i := p.Y*s.width + p.X
	return s.cells[i].Ch
}
func (s *snake) setCell(p position, c termbox.Cell) {
	i := p.Y*s.width + p.X
	s.cells[i] = c
}

func (s *snake) drawBorder() {
	for x := 0; x < s.width; x++ {
		s.setCell(position{x, 0}, border)
		s.setCell(position{x, s.height - 1}, border)
	}
	for y := 0; y < s.height-1; y++ {
		s.setCell(position{0, y}, border)
		s.setCell(position{s.width - 1, y}, border)
	}
}

func (s *snake) placeFood() {
	for {
		// a random empty cell
		x := rand.Intn(s.width-2) + 1
		y := rand.Intn(s.height-2) + 1
		foodp := position{x, y}
		r := s.getCellRune(foodp)
		if r != ' ' {
			continue
		}
		s.setCell(foodp, food)
		return
	}
}

func (s *snake) startSnake() {
	// a random cell somewhat near the center
	x := rand.Intn(s.width/2) + s.width/4
	y := rand.Intn(s.height/2) + s.height/4
	head := position{x, y}
	s.setCell(head, snakeHead)
	s.body = append(s.body[:0], head)
	s.heading = direction(rand.Intn(4))
}

func (s *snake) doMove(move direction) bool {
	head := s.body[len(s.body)-1]
	s.setCell(head, snakeBody)
	head = head.next(move)
	s.heading = move
	s.body = append(s.body, head)
	r := s.getCellRune(head)
	s.setCell(head, snakeHead)
	gameOver := false
	switch r {
	case food.Ch:
		s.placeFood()
	case border.Ch, snakeBody.Ch:
		gameOver = true
		fallthrough
	case empty.Ch:
		s.setCell(s.body[0], empty)
		s.body = s.body[1:]
	default:
		panic(r)
	}
	s.flush()
	return gameOver
}

const (
	fg = termbox.ColorWhite
	bg = termbox.ColorBlack
)

// Symbols to use.
// Could use Unicode instead of simple ASCII.
var (
	empty     = termbox.Cell{Ch: ' ', Bg: bg, Fg: fg}
	border    = termbox.Cell{Ch: '+', Bg: bg, Fg: termbox.ColorBlue}
	snakeBody = termbox.Cell{Ch: '#', Bg: bg, Fg: termbox.ColorGreen}
	snakeHead = termbox.Cell{Ch: 'O', Bg: bg, Fg: termbox.ColorYellow | termbox.AttrBold}
	food      = termbox.Cell{Ch: '@', Bg: bg, Fg: termbox.ColorRed}
)


F factors(=n)
   [Int] rt
   V f = 2
   I n == 1
      rt.append(1)
   E
      L
         I 0 == (n % f)
            rt.append(f)
            n I/= f
            I n == 1
               R rt
         E
            f++
   R rt

F sum_digits(=n)
   V sum = 0
   L n > 0
      V m = n % 10
      sum += m
      n -= m
      n I/= 10
   R sum

F add_all_digits(lst)
   V sum = 0
   L(i) 0 .< lst.len
      sum += sum_digits(lst[i])
   R sum

F list_smith_numbers(cnt)
   [Int] r
   L(i) 4 .< cnt
      V fac = factors(i)
      I fac.len > 1
         I sum_digits(i) == add_all_digits(fac)
            r.append(i)
   R r

V sn = list_smith_numbers(10'000)
print(‘Count of Smith Numbers below 10k: ’sn.len)
print()
print(‘First 15 Smith Numbers:’)
print_elements(sn[0.<15])
print()
print(‘Last 12 Smith Numbers below 10000:’)
print_elements(sn[(len)-12..])


*        Singly-linked list/Element definition  07/02/2017
LISTSINA CSECT
         USING  LISTSINA,R13       base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         STM    R14,R12,12(R13)    prolog
         ST     R13,4(R15)         " <-
         ST     R15,8(R13)         " ->
         LR     R13,R15            " addressability
*        Allocate A
         GETMAIN RU,LV=12          get storage
         USING  NODE,R11           make storage addressable
         LR     R11,R1             "
         MVC    VAL,=CL8'A'        val='A'
         MVC    NEXT,=A(0)
         DROP   R11                base no longer needed
         ST     R11,A              [email protected]
*        Init LIST
         ST     R11,LIST           init LIST with A
*        Allocate C
         GETMAIN RU,LV=12          get storage
         USING  NODE,R11           make storage addressable
         LR     R11,R1             "
         MVC    VAL,=CL8'C'        val='C'
         MVC    NEXT,=A(0)
         DROP   R11                base no longer needed
         ST     R11,C              [email protected]
*        Insert C After A
         MVC    P1,A
         MVC    P2,C
         LA     R1,PARML
         BAL    R14,INSERTAF
*        Allocate B
         GETMAIN RU,LV=12          get storage
         USING  NODE,R11           make storage addressable
         LR     R11,R1             "
         MVC    VAL,=CL8'B'        val='B'
         MVC    NEXT,=A(0)
         DROP   R11                base no longer needed
         ST     R11,B              [email protected]
*        Insert B After A
         MVC    P1,A
         MVC    P2,B
         LA     R1,PARML
         BAL    R14,INSERTAF
*        List all
         L      R11,LIST
         USING  NODE,R11           address node
LOOP     C      R11,=A(0)
         BE     ENDLIST
         XPRNT  VAL,8
         L      R11,NEXT
         B      LOOP
ENDLIST  DROP   R11
         FREEMAIN A=A,LV=12        free A
         FREEMAIN A=B,LV=12        free B
         FREEMAIN A=C,LV=12        free C
RETURN   L      R13,4(0,R13)       epilog
         LM     R14,R12,12(R13)    " restore
         XR     R15,R15            " rc=0
         BR     R14                exit
LIST     DS     A                  list head
A        DS     A
B        DS     A
C        DS     A
PARML    DS     0A
P1       DS     A
P2       DS     A
INSERTAF CNOP   0,4
         L      R2,0(R1)           @A
         L      R3,4(R1)           @B
         USING  NODE,R2            ->A
         L      R4,NEXT            @C
         DROP   R2
         USING  NODE,R3            ->B
         ST     R4,NEXT            [email protected]
         DROP   R3
         USING  NODE,R2            ->A
         ST     R3,NEXT            [email protected]
         DROP   R2
         BR     R14                return
         LTORG                     all literals
NODE     DSECT                     node (size=12)
VAL      DS     CL8
NEXT     DS     A
         YREGS
         END    LISTSINA


{-# LANGUAGE TemplateHaskell #-}
import Control.Monad.Random (getRandomRs)
import Graphics.Gloss.Interface.Pure.Game
import Lens.Micro ((%~), (^.), (&), set)
import Lens.Micro.TH (makeLenses)

--------------------------------------------------------------------------------
-- all data types

data Snake = Snake { _body :: [Point], _direction :: Point }
makeLenses ''Snake

data World = World { _snake :: Snake , _food :: [Point]
                   , _score :: Int , _maxScore :: Int }
makeLenses ''World

--------------------------------------------------------------------------------
-- everything snake can do

moves (Snake b d) = Snake (step b d : init b) d
eats  (Snake b d) = Snake (step b d : b) d
bites (Snake b _) = any (== head b)
step ((x,y):_) (a,b) = (x+a, y+b)

turn (x',y') (Snake b (x,y)) | (x+x',y+y') == (0,0)  = Snake b (x,y)
                             | otherwise             = Snake b (x',y')

--------------------------------------------------------------------------------
-- all randomness

createWorld = do xs <- map fromIntegral <$> getRandomRs (2, 38 :: Int)
                 ys <- map fromIntegral <$> getRandomRs (2, 38 :: Int)
                 return (Ok, World snake (zip xs ys) 0 0)
                 where
                   snake = Snake [(20, 20)] (1,0)

-------------------------------------------------------------------------------
-- A tyny DSL for declarative description of business logic

data Status = Ok | Fail | Stop

continue = \x -> (Ok, x)
stop     = \x -> (Stop, x)
f >>> g  = \x -> case f x of { (Ok, y) -> g y; b -> b }    -- chain composition
f <|> g  = \x -> case f x of { (Fail, _) -> g x; b -> b }  -- alternative
p ==> f  = \x -> if p x then f x else (Fail, x)            -- condition
l .& f   = continue . (l %~ f)                             -- modification
l .= y   = continue . set l y                              -- setting

--------------------------------------------------------------------------------
-- all business logic

updateWorld _ =  id >>> (snakeEats <|> snakeMoves)
  where
    snakeEats  = (snakeFindsFood ==> (snake .& eats)) >>>
                 (score .& (+1)) >>> (food .& tail)

    snakeMoves = (snakeBitesTail ==> stop) <|>
                 (snakeHitsWall ==> stop) <|>
                 (snake .& moves)

    snakeFindsFood w = (w^.snake & moves) `bites` (w^.food & take 1)
    snakeBitesTail w = (w^.snake) `bites` (w^.snake.body & tail)
    snakeHitsWall w  = (w^.snake.body) & head & isOutside
    isOutside (x,y) = or [x <= 0, 40 <= x, y <= 0, 40 <= y]

--------------------------------------------------------------------------------
-- all event handing

handleEvents e (s,w) = f w
  where f = case s of
          Ok -> case e of
            EventKey (SpecialKey k) _ _ _ -> case k of
              KeyRight -> snake .& turn (1,0)
              KeyLeft  -> snake .& turn (-1,0)
              KeyUp    -> snake .& turn (0,1)
              KeyDown  -> snake .& turn (0,-1)
              _-> continue
            _-> continue
          _-> \w -> w & ((snake.body) .= [(20,20)]) >>>
                         (maxScore .& max (w^.score)) >>> (score .= 0)

--------------------------------------------------------------------------------
-- all graphics

renderWorld (s, w) = pictures [frame, color c drawSnake, drawFood, showScore]
  where c = case s of { Ok -> orange; _-> red }
        drawSnake = foldMap (rectangleSolid 10 10 `at`) (w^.snake.body)
        drawFood = color blue $ circleSolid 5 `at` (w^.food & head)
        frame = color black $ rectangleWire 400 400
        showScore = color orange $ scale 0.2 0.2 $ txt `at` (-80,130)
        txt = Text $ mconcat ["Score: ", w^.score & show
                             ,"   Maximal score: ", w^.maxScore & show]
        at p (x,y) = Translate (10*x-200) (10*y-200) p

--------------------------------------------------------------------------------

main = do world <- createWorld
          play inW white 7 world renderWorld handleEvents updateWorld
  where inW = InWindow "The Snake" (400, 400) (10, 10)


*        Smith numbers -           02/05/2017
SMITHNUM CSECT
         USING  SMITHNUM,R13       base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         STM    R14,R12,12(R13)    save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         LA     R10,PG             pgi=0
         LA     R6,4               i=4
       DO WHILE=(C,R6,LE,N)        do i=4 to n
         LR     R1,R6                i
         BAL    R14,SUMD             call sumd(i)
         ST     R0,SS                ss=sumd(i)
         LR     R1,R6                i
         BAL    R14,SUMFACTR         call sumfactr(i)
       IF C,R0,EQ,SS THEN            if sumd(i)=sumfactr(i) then
         L      R2,NN                  nn
         LA     R2,1(R2)               nn+1
         ST     R2,NN                  nn=nn+1
         XDECO  R6,XDEC                i
         MVC    0(5,R10),XDEC+7        output i
         LA     R10,5(R10)             pgi+=5
         L      R4,IPG                 ipg
         LA     R4,1(R4)               ipg+1
         ST     R4,IPG                 ipg=ipg+1
       IF C,R4,EQ,=F'16' THEN          if ipg=16 then
         XPRNT  PG,80                    print buffer
         MVC    PG,=CL80' '              clear buffer
         LA     R10,PG                   pgi=0
         MVC    IPG,=F'0'                ipg=0
       ENDIF    ,                      endif
       ENDIF    ,                    endif
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         L      R4,IPG             ipg
       IF LTR,R4,NZ,R4 THEN        if ipg<>0 then
         XPRNT  PG,80                print buffer
       ENDIF    ,                  endif
         L      R1,NN              nn
         XDECO  R1,XDEC            edit nn
         MVC    PGT(4),XDEC+8      output nn
         L      R1,N               n
         XDECO  R1,XDEC            edit n
         MVC    PGT+28(5),XDEC+7   output n
         XPRNT  PGT,80             print
         L      R13,4(0,R13)       restore previous savearea pointer
         LM     R14,R12,12(R13)    restore previous context
         XR     R15,R15            rc=0
         BR     R14                exit
*------- ----   ----------------------------------------
SUMD     EQU    *                  sumd(x)
         SR     R0,R0              s=0
       DO WHILE=(LTR,R1,NZ,R1)     do while x<>0
         LR     R2,R1                x
         SRDA   R2,32                ~
         D      R2,=F'10'            x/10
         LR     R1,R3                x=x/10
         AR     R0,R2                s=s+x//10
       ENDDO    ,                  enddo while
         BR     R14                return s
*------- ----   ----------------------------------------
SUMFACTR EQU    *                  sumfactr(z)
         ST     R14,SAVER14        store r14
         ST     R1,ZZ              z
         SR     R8,R8              m=0
         SR     R9,R9              f=0
         L      R4,ZZ              z
         SRDA   R4,32              ~
         D      R4,=F'2'           z/2
       DO WHILE=(LTR,R4,Z,R4)      do while z//2=0
         LA     R8,2(R8)             m=m+2
         LA     R9,1(R9)             f=f+1
         L      R5,ZZ                z
         SRA    R5,1                 z/2
         ST     R5,ZZ                z=z/2
         LA     R4,0                 z
         D      R4,=F'2'             z/2
       ENDDO    ,                  enddo while
         L      R4,ZZ              z
         SRDA   R4,32              ~
         D      R4,=F'3'           z/3
       DO WHILE=(LTR,R4,Z,R4)      do while z//3=0
         LA     R8,3(R8)             m=m+3
         LA     R9,1(R9)             f=f+1
         L      R4,ZZ                z
         SRDA   R4,32                ~
         D      R4,=F'3'             z/3
         ST     R5,ZZ                z=z/3
         LA     R4,0                 z
         D      R4,=F'3'             z/3
       ENDDO    ,                  enddo while
         LA     R7,5               do j=5 by 2 while j<=z and j*j<=n
WHILEJ   C      R7,ZZ                if j>z
         BH     EWHILEJ              then leave while
         LR     R5,R7                j
         MR     R4,R7                *j
         C      R5,N                 if j*j>n
         BH     EWHILEJ              then leave while
         LR     R4,R7                j
         SRDA   R4,32                ~
         D      R4,=F'3'             j/3
         LTR    R4,R4                if j//3=0
         BZ     ITERJ                then goto iterj
         L      R4,ZZ                z
         SRDA   R4,32                ~
         DR     R4,R7                z/j
       DO WHILE=(LTR,R4,Z,R4)        do while z//j=0
         LA     R9,1(R9)               f=f+1
         LR     R1,R7                  j
         BAL    R14,SUMD               call sumd(j)
         AR     R8,R0                  m=m+sumd(j)
         L      R4,ZZ                  z
         SRDA   R4,32                  ~
         DR     R4,R7                  z/j
         ST     R5,ZZ                  z=z/j
         LA     R4,0                   ~
         DR     R4,R7                  z/j
       ENDDO    ,                    enddo while
ITERJ    LA     R7,2(R7)             j+=2
         B      WHILEJ             enddo
EWHILEJ  L      R4,ZZ              z
       IF C,R4,NE,=F'1' THEN       if z<>1 then
         LA     R9,1(R9)             f=f+1
         L      R1,ZZ                z
         BAL    R14,SUMD             call sumd(z)
         AR     R8,R0                m=m+sumd(z)
       ENDIF    ,                  endif
       IF C,R9,LT,=F'2' THEN       if f<2 then
         SR     R8,R8                mm=0
       ENDIF    ,                  endif
         LR     R0,R8              return m
         L      R14,SAVER14        restore r14
         BR     R14                return
SAVER14  DS     A                  save r14
*        ----   ----------------------------------------
N        DC     F'10000'           n
NN       DC     F'0'               nn
IPG      DC     F'0'               ipg
SS       DS     F                  ss
ZZ       DS     F                  z
PG       DC     CL80' '            buffer
PGT      DC     CL80'xxxx smith numbers found <= xxxxx'
XDEC     DS     CL12               temp
         YREGS
         END    SMITHNUM


CARD FUNC SumDigits(CARD n)
  CARD res,a

  res=0
  WHILE n#0
  DO
    res==+n MOD 10
    n==/10
  OD
RETURN (res)

CARD FUNC PrimeFactors(CARD n CARD ARRAY f)
  CARD a,count

  a=2 count=0
  DO
    IF n MOD a=0 THEN
      f(count)=a
      count==+1
      n==/a
      IF n=1 THEN
        RETURN (count)
      FI
    ELSE
      a==+1
    FI
  OD
RETURN (0)

PROC Main()
  CARD n,i,s1,s2,count,tmp
  CARD ARRAY f(100)

  FOR n=4 TO 10000
  DO
    count=PrimeFactors(n,f)
    IF count>=2 THEN
      s1=SumDigits(n)
      s2=0
      FOR i=0 TO count-1
      DO
        tmp=f(i)
        s2==+SumDigits(tmp)
      OD
      IF s1=s2 THEN
        PrintC(n) Put(32)
      FI
    FI
    Poke(77,0) ;turn off the attract mode
  OD
RETURN


with Ada.Text_IO;

procedure smith is
  type Vector is array (natural range <>) of Positive;
  empty_vector : constant Vector(1..0):= (others=>1);

  function digits_sum (n : Positive) return Positive is
  (if n < 10 then n else n mod 10 + digits_sum (n / 10));

  function prime_factors (n : Positive; d : Positive := 2) return Vector is
  (if n = 1 then empty_vector elsif n mod d = 0 then prime_factors (n / d, d) & d
   else prime_factors (n, d + (if d=2 then 1 else 2)));

  function vector_digits_sum (v : Vector) return Natural is
  (if v'Length = 0 then 0 else digits_sum (v(v'First)) + vector_digits_sum (v(v'First+1..v'Last)));

begin
  for n in 1..10000 loop
    declare
      primes : Vector := prime_factors (n);
    begin
      if  primes'Length > 1 and then vector_digits_sum (primes) = digits_sum (n) then
        Ada.Text_IO.put (n'img);
      end if;
    end;
  end loop;
end smith;


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program defList.s   */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"

.equ NBELEMENTS,      100              // list size
/*******************************************/
/* Structures                               */
/********************************************/
/* structure linkedlist*/
    .struct  0
llist_next:                    // next element
    .struct  llist_next + 8
llist_value:                   // element value
    .struct  llist_value + 8
llist_fin:
/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szMessInitListe:         .asciz "List initialized.\n"
szCarriageReturn:        .asciz "\n"
/* datas error display */
szMessErreur:            .asciz "Error detected.\n"
/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss
lList1:              .skip llist_fin * NBELEMENTS    // list memory place
/*******************************************/
/*  code section                           */
/*******************************************/
.text
.global main
main:
    ldr x0,qAdrlList1
    mov x1,#0
    str x1,[x0,#llist_next]
    ldr x0,qAdrszMessInitListe
    bl affichageMess

100:                                    // standard end of the program
    mov x8, #EXIT                       // request to exit program
    svc 0                               // perform system call
qAdrszMessInitListe:       .quad szMessInitListe
qAdrszMessErreur:          .quad szMessErreur
qAdrszCarriageReturn:      .quad szCarriageReturn
qAdrlList1:                .quad lList1
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


(let ((elem 8)
      (next (list 6 7 5 3 0 9)))
  (cons elem next))


DEFINE PTR="CARD"

TYPE ListNode=[
  BYTE data
  PTR nxt]


package
{
	public class Node
	{
		public var data:Object = null;
		public var link:Node = null;

		public function Node(obj:Object)
		{
			data = obj;
		}
	}
}


type Link;
type Link_Access is access Link;
type Link is record
   Next : Link_Access := null;
   Data : Integer;
end record;


# -*- coding: utf-8 -*- #
CO REQUIRES:
  MODE OBJVALUE = ~ # Mode/type of actual obj to be stacked #
END CO

MODE OBJNEXTLINK = STRUCT(
  REF OBJNEXTLINK next,
  OBJVALUE value # ... etc. required #
);

PROC obj nextlink new = REF OBJNEXTLINK:
  HEAP OBJNEXTLINK;

PROC obj nextlink free = (REF OBJNEXTLINK free)VOID:
  next OF free := obj stack empty # give the garbage collector a BIG hint #


const L = 1, R = 2, D = 4, U = 8;
var block = 24, wid = 30, hei = 20, frameR = 7, fruit, snake;
function Snake() {
    this.length = 1;
    this.alive = true;
    this.pos = createVector( 1, 1 );
    this.posArray = [];
    this.posArray.push( createVector( 1, 1 ) );
    this.dir = R;
    this.draw = function() {
        fill( 130, 190, 0 );
        var pos, i = this.posArray.length - 1, l = this.length;
        while( true ){
            pos = this.posArray[i--];
            rect( pos.x * block, pos.y * block, block, block );
            if( --l == 0 ) break;
        }
    }
    this.eat = function( frut ) {
        var b = this.pos.x == frut.x && this.pos.y == frut.y;
        if( b ) this.length++;
        return b;
    }
    this.overlap = function() {
        var len = this.posArray.length - 1;
        for( var i = len; i > len - this.length; i-- ) {
            tp = this.posArray[i];
            if( tp.x === this.pos.x && tp.y === this.pos.y ) return true;
        }
        return false;
    }
    this.update = function() {
        if( !this.alive ) return;
        switch( this.dir ) {
            case L:
                this.pos.x--; if( this.pos.x < 1 ) this.pos.x = wid - 2;
            break;
            case R:
                this.pos.x++; if( this.pos.x > wid - 2 ) this.pos.x = 1;
            break;
            case U:
                this.pos.y--; if( this.pos.y < 1 ) this.pos.y = hei - 2;
            break;
            case D:
                this.pos.y++; if( this.pos.y > hei - 2 ) this.pos.y = 1;
            break;
        }
        if( this.overlap() ) { this.alive = false; } else {
            this.posArray.push( createVector( this.pos.x, this.pos.y ) );
            if( this.posArray.length > 5000 ) { this.posArray.splice( 0, 1 ); }
        }
    }
}
function Fruit() {
    this.fruitTime = true;
    this.pos = createVector();
    this.draw = function() {
        fill( 200, 50, 20 );
        rect( this.pos.x * block, this.pos.y * block, block, block );
    }

    this.setFruit = function() {
        this.pos.x = floor( random( 1, wid - 1 ) );
        this.pos.y = floor( random( 1, hei - 1 ) );
        this.fruitTime = false;
    }
}
function setup() {
    createCanvas( block * wid, block * hei );
    noStroke(); frameRate( frameR );
    snake = new Snake();fruit = new Fruit();
}
function keyPressed() {
    switch( keyCode ) {
        case LEFT_ARROW: snake.dir = L; break;
        case RIGHT_ARROW: snake.dir = R; break;
        case UP_ARROW: snake.dir = U; break;
        case DOWN_ARROW: snake.dir = D;
    }
}
function draw() {
    background( color( 0, 0x22, 0 ) );
    fill( 20, 50, 120 );
    for( var i = 0; i < wid; i++ ) {
        rect( i * block, 0, block, block );
        rect( i * block, height - block, block, block );
    }
    for( var i = 1; i < hei - 1; i++ ) {
        rect( 1, i * block, block, block );
        rect( width - block, i * block, block, block );
    }
    if( fruit.fruitTime ) {
        fruit.setFruit();
        frameR += .2;
        frameRate( frameR );
    }
    fruit.draw();
    snake.update();
    if( snake.eat( fruit.pos ) ) {
        fruit.fruitTime = true;
    }
    snake.draw();
    fill( 200 );
    textStyle( BOLD ); textAlign( RIGHT ); textSize( 120 );
    text( ""+( snake.length - 1 ), 690, 440 );
    if( !snake.alive ) text( "THE END", 630, 250 );
}


# sieve of Eratosthene: sets s[i] to TRUE if i is prime, FALSE otherwise #
PROC sieve = ( REF[]BOOL s )VOID:
     BEGIN
        # start with everything flagged as prime                             #
        FOR i TO UPB s DO s[ i ] := TRUE OD;
        # sieve out the non-primes                                           #
        s[ 1 ] := FALSE;
        FOR i FROM 2 TO ENTIER sqrt( UPB s ) DO
            IF s[ i ] THEN FOR p FROM i * i BY i TO UPB s DO s[ p ] := FALSE OD FI
        OD
     END # sieve # ;

# construct a sieve of primes up to the maximum number required for the task #
INT max number = 10 000;
[ 1 : max number ]BOOL is prime;
sieve( is prime );

# returns the sum of the digits of n                                         #
OP DIGITSUM = ( INT n )INT:
   BEGIN
       INT sum  := 0;
       INT rest := ABS n;
       WHILE rest > 0 DO
           sum +:= rest MOD 10;
           rest OVERAB 10
       OD;
       sum
   END # DIGITSUM # ;

# returns TRUE if n is a Smith number, FALSE otherwise                       #
# n must be between 1 and max number                                         #
PROC is smith = ( INT n )BOOL:
     IF is prime[ ABS n ] THEN
         # primes are not Smith numbers                                      #
         FALSE
     ELSE
         # find the factors of n and sum the digits of the factors           #
         INT rest             := ABS n;
         INT factor digit sum := 0;
         INT factor           := 2;
         WHILE factor < max number AND rest > 1 DO
             IF NOT is prime[ factor ] THEN
                 # factor isn't a prime                                      #
                 factor +:= 1
             ELSE
                 # factor is a prime                                         #
                 IF rest MOD factor /= 0 THEN
                     # factor isn't a factor of n                            #
                     factor +:= 1
                 ELSE
                     # factor is a factor of n                               #
                     rest OVERAB factor;
                     factor digit sum +:= DIGITSUM factor
                 FI
             FI
         OD;
         ( factor digit sum = DIGITSUM n )
     FI # is smith # ;

# print all the Smith numbers below the maximum required                     #
INT smith count := 0;
FOR n TO max number - 1 DO
    IF is smith( n ) THEN
        # have a smith number #
        print( ( whole( n, -7 ) ) );
        smith count +:= 1;
        IF smith count MOD 10 = 0 THEN
            print( ( newline ) )
        FI
    FI
OD;
print( ( newline, "THere are ", whole( smith count, -7 ), " Smith numbers below ", whole( max number, -7 ), newline ) )


    % record type to hold a singly linked list of integers                    %
    record ListI ( integer iValue; reference(ListI) next );

    % declare a variable to hold a list                                       %
    reference(ListI) head;

    % create a list of integers                                               %
    head := ListI( 1701, ListI( 9000, ListI( 42, ListI( 90210, null ) ) ) );


/* ARM assembly Raspberry PI  */
/*  program defList.s   */

/* Constantes    */
.equ STDOUT, 1                           @ Linux output console
.equ EXIT,   1                           @ Linux syscall
.equ READ,   3
.equ WRITE,  4

.equ NBELEMENTS,      100                @ list size

/*******************************************/
/* Structures                               */
/********************************************/
/* structure linkedlist*/
    .struct  0
llist_next:                             @ next element
    .struct  llist_next + 4
llist_value:                            @ element value
    .struct  llist_value + 4
llist_fin:
/* Initialized data */
.data
szMessInitListe:         .asciz "List initialized.\n"
szCarriageReturn:        .asciz "\n"
/* datas error display */
szMessErreur:            .asciz "Error detected.\n"

/* UnInitialized data */
.bss
lList1:                  .skip llist_fin * NBELEMENTS    @ list memory place

/*  code section */
.text
.global main
main:
    ldr r0,iAdrlList1
    mov r1,#0
    str r1,[r0,#llist_next]
    ldr r0,iAdrszMessInitListe
    bl affichageMess

100:                                    @ standard end of the program
    mov r7, #EXIT                       @ request to exit program
    svc 0                               @ perform system call
iAdrszMessInitListe:       .int szMessInitListe
iAdrszMessErreur:          .int szMessErreur
iAdrszCarriageReturn:      .int szCarriageReturn
iAdrlList1:                .int lList1
/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                       @ save  registers
    mov r2,#0                                   @ counter length */
1:                                              @ loop length calculation
    ldrb r1,[r0,r2]                             @ read octet start position + index
    cmp r1,#0                                   @ if 0 its over
    addne r2,r2,#1                              @ else add 1 in the length
    bne 1b                                      @ and loop
                                                @ so here r2 contains the length of the message
    mov r1,r0                                   @ address message in r1
    mov r0,#STDOUT                              @ code to write to the standard output Linux
    mov r7, #WRITE                              @ code call system "write"
    svc #0                                      @ call system
    pop {r0,r1,r2,r7,lr}                        @ restaur registers
    bx lr                                       @ return


(* The Rosetta Code linear list type can contain any [email protected]
   (The ‘@’ means it doesn’t have to be the size of a pointer.
   You can read {0 <= n} as ‘for all non-negative n’. *)
dataviewtype rclist_vt (vt : [email protected]+, n : int) =
| rclist_vt_nil (vt, 0)
| {0 <= n} rclist_vt_cons (vt, n + 1) of (vt, rclist_vt (vt, n))

(* A lemma one will need: lists never have negative lengths. *)
extern prfun {vt : [email protected]}
lemma_rclist_vt_param
          {n : int}
          (lst : !rclist_vt (vt, n)) :<prf> [0 <= n] void

(* Proof of the lemma. *)
primplement {vt}
lemma_rclist_vt_param lst =
  case+ lst of
  | rclist_vt_nil () => ()
  | rclist_vt_cons _ => ()


digitSum: function [v][
    n: new v
    result: new 0
    while [n > 0][
        'result + n % 10
        'n / 10
    ]
    return result
]

smith?: function [z][
    return
        (prime? z) ? -> false
                     -> (digitSum z) = sum map factors.prime z 'num [digitSum num]
]
found: 0
loop 1..10000 'x [
    if smith? x [
        found: found + 1
        prints (pad to :string x 6) ++ " "
        if 0 = found % 10 -> print ""
    ]
]
print ""


# syntax: GAWK -f SMITH_NUMBERS.AWK
# converted from C
BEGIN {
    limit = 10000
    printf("Smith Numbers < %d:\n",limit)
    for (a=4; a<limit; a++) {
      num_factors = num_prime_factors(a)
      if (num_factors < 2) {
        continue
      }
      prime_factors(a)
      if (sum_digits(a) == sum_factors(num_factors)) {
        printf("%4d ",a)
        if (++cr % 16 == 0) {
          printf("\n")
        }
      }
      delete arr
    }
    printf("\n")
    exit(0)
}
function num_prime_factors(x,  p,pf) {
    p = 2
    pf = 0
    if (x == 1) {
      return(1)
    }
    while (1) {
      if (!(x % p)) {
        pf++
        x = int(x/p)
        if (x == 1) {
          return(pf)
        }
      }
      else {
        p++
      }
    }
}
function prime_factors(x,  p,pf) {
    p = 2
    pf = 0
    if (x == 1) {
      arr[pf] = 1
    }
    else {
      while (1) {
        if (!(x % p)) {
          arr[pf++] = p
          x = int(x/p)
          if (x == 1) {
            return
          }
        }
        else {
          p++
        }
      }
    }
}
function sum_digits(x,  sum,y) {
    while (x) {
      y = x % 10
      sum += y
      x = int(x/10)
    }
    return(sum)
}
function sum_factors(x,  a,sum) {
    sum = 0
    for (a=0; a<x; a++) {
      sum += sum_digits(arr[a])
    }
    return(sum)
}


element = 5 ; data
element_next = element2  ; link to next element


BEGIN {
    NIL = 0
    HEAD = 1
    LINK = 1
    VALUE = 2

    delete list
    initList()
}

function initList() {
    delete list
    list[HEAD] = makeNode(NIL, NIL)
}

function makeNode(link, value) {
    return link SUBSEP value
}

function getNode(part, nodePtr,    linkAndValue) {
    split(list[nodePtr], linkAndValue, SUBSEP)
    return linkAndValue[part]
}


Lbl LINK
r₂→{r₁}ʳ
0→{r₁+2}ʳ
r₁
Return

Lbl NEXT
{r₁+2}ʳ
Return

Lbl VALUE
{r₁}ʳ
Return


struct link {
  struct link *next;
  int data;
};


using Makie

mutable struct SnakeGame
    height
    width
    snake
    food
end

function SnakeGame(;height=6, width=8)
    snake = [rand(CartesianIndices((height, width)))]
    food = rand(CartesianIndices((height, width)))
    while food == snake[1]
        food = rand(CartesianIndices((height, width)))
    end
    SnakeGame(height, width, snake, food)
end

function step!(game, direction)
    next_head = game.snake[1] + direction
    next_head = CartesianIndex(mod.(next_head.I, Base.OneTo.((game.height, game.width))))  # allow crossing boundry
    if is_valid(game, next_head)
        pushfirst!(game.snake, next_head)
        if next_head == game.food
            length(game.snake) < game.height * game.width && init_food!(game)
        else
            pop!(game.snake)
        end
        true
    else
        false
    end
end

is_valid(game, position) = position ∉ game.snake

function init_food!(game)
    p = rand(CartesianIndices((game.height, game.width)))
    while !is_valid(game, p)
        p = rand(CartesianIndices((game.height, game.width)))
    end
    game.food = p
end

function play(;n=10,t=0.5)
    game = Node(SnakeGame(;width=n,height=n))
    scene = Scene(resolution = (1000, 1000), raw = true, camera = campixel!)
    display(scene)

    area = scene.px_area
    poly!(scene, area)

    grid_size = @lift((widths($area)[1] / $game.height, widths($area)[2] / $game.width))

    snake_boxes = @lift([FRect2D((p.I .- (1,1)) .* $grid_size , $grid_size) for p in $game.snake])
    poly!(scene, snake_boxes, color=:blue, strokewidth = 5, strokecolor = :black)

    snake_head_box = @lift(FRect2D(($game.snake[1].I .- (1,1)) .* $grid_size , $grid_size))
    poly!(scene, snake_head_box, color=:black)
    snake_head = @lift((($game.snake[1].I .- 0.5) .* $grid_size))
    scatter!(scene, snake_head, marker='◉', color=:blue, [email protected](minimum($grid_size)))

    food_position = @lift(($game.food.I .- (0.5,0.5)) .* $grid_size)
    scatter!(scene, food_position, color=:red, marker='♥', [email protected](minimum($grid_size)))

    score_text = @lift("Score: $(length($game.snake)-1)")
    text!(scene, score_text, color=:gray, position = @lift((widths($area)[1]/2, widths($area)[2])), textsize = 50, align = (:center, :top))

    direction = Ref{Any}(nothing)

    on(scene.events.keyboardbuttons) do but
        if ispressed(but, Keyboard.left)
            direction[] = CartesianIndex(-1,0)
        elseif ispressed(but, Keyboard.up)
            direction[] = CartesianIndex(0,1)
        elseif ispressed(but, Keyboard.down)
            direction[] = CartesianIndex(0,-1)
        elseif ispressed(but, Keyboard.right)
            direction[] = CartesianIndex(1,0)
        end
    end

    last_dir = nothing
    while true
        # avoid turn back
        if !isnothing(direction[]) && (isnothing(last_dir) || direction[] != -last_dir)
            last_dir = direction[]
        end
        if !isnothing(last_dir)
            if step!(game[], last_dir)
                game[] = game[]
            else
                break
            end
        end
        sleep(t)
    end
end

play()


// Kotlin Native v0.5

import kotlinx.cinterop.*
import platform.posix.*
import platform.windows.*

const val WID = 60
const val HEI = 30
const val MAX_LEN = 600
const val NUL = '\u0000'

enum class Dir { NORTH, EAST, SOUTH, WEST }

class Snake {
    val console: HANDLE
    var alive = false
    val brd = CharArray(WID * HEI)
    var dir = Dir.NORTH
    val snk = nativeHeap.allocArray<COORD>(MAX_LEN)
    lateinit var head: COORD
    var tailIdx = 0
    var headIdx = 0
    var points = 0

    init {
        console = GetStdHandle(STD_OUTPUT_HANDLE)!!
        SetConsoleTitleW("Snake")
        memScoped {
            val coord = alloc<COORD>().apply { X = (WID + 1).toShort(); Y = (HEI + 2).toShort() }
            SetConsoleScreenBufferSize(console, coord.readValue())
            val rc = alloc<SMALL_RECT>().apply {
                Left = 0; Top = 0; Right = WID.toShort(); Bottom = (HEI + 1).toShort()
            }
            SetConsoleWindowInfo(console, TRUE, rc.ptr)
            val ci = alloc<CONSOLE_CURSOR_INFO>().apply { dwSize = 1; bVisible = FALSE }
            SetConsoleCursorInfo(console, ci.ptr)
        }
    }

    fun play() {
        while (true) {
            createfield()
            alive = true
            while (alive) {
                drawfield()
                readKey()
                moveSnake()
                Sleep(50)
            }
            memScoped {
                val c = alloc<COORD>().apply { X = 0; Y = (HEI + 1).toShort() }
                SetConsoleCursorPosition(console, c.readValue())
            }
            SetConsoleTextAttribute(console, 0x000b)
            print("Play again [Y/N]? ")
            val a = readLine()!!.toLowerCase()
            if (a.length > 0 && a[0] != 'y') {
                nativeHeap.free(snk)
                return
            }
        }
    }

    private fun createfield() {
        memScoped {
            val coord = alloc<COORD>().apply { X = 0; Y = 0 }
            val c = alloc<DWORDVar>()
            FillConsoleOutputCharacterW(console, 32, (HEI + 2) * 80, coord.readValue(), c.ptr)
            FillConsoleOutputAttribute(console, 0x0000, (HEI + 2) * 80, coord.readValue(), c.ptr)
            SetConsoleCursorPosition(console, coord.readValue())
        }
        for (x in 0 until WID * HEI) brd[x] = NUL
        for (x in 0 until WID) {
            brd[x + WID * (HEI - 1)] = '+'
            brd[x] = '+'
        }
        for (y in 1 until HEI) {
            brd[WID - 1 + WID * y] = '+'
            brd[WID * y] = '+'
        }
        var xx: Int
        var yy: Int
        do {
            xx = rand() % WID
            yy = rand() % (HEI shr 1) + (HEI shr 1)
        }
        while (brd[xx + WID * yy] != NUL)
        brd[xx + WID * yy] = '@'
        tailIdx = 0
        headIdx = 4
        xx = 3
        yy = 2
        for (cc in tailIdx until headIdx) {
            brd[xx + WID * yy] = '#'
            snk[cc].X = (3 + cc).toShort()
            snk[cc].Y = 2
        }
        head = snk[3]
        dir = Dir.EAST
        points = 0
    }

    private fun readKey() {
        if ((GetAsyncKeyState(39).toInt() and 0x8000) != 0) dir = Dir.EAST
        if ((GetAsyncKeyState(37).toInt() and 0x8000) != 0) dir = Dir.WEST
        if ((GetAsyncKeyState(38).toInt() and 0x8000) != 0) dir = Dir.NORTH
        if ((GetAsyncKeyState(40).toInt() and 0x8000) != 0) dir = Dir.SOUTH
    }

    private fun drawfield() {
        memScoped {
            val coord = alloc<COORD>()
            var t = NUL
            for (y in 0 until HEI) {
                coord.Y = y.toShort()
                for (x in 0 until WID) {
                    t = brd[x + WID * y]
                    if (t == NUL) continue
                    coord.X = x.toShort()
                    SetConsoleCursorPosition(console, coord.readValue())
                    if (coord.X == head.X && coord.Y == head.Y) {
                        SetConsoleTextAttribute(console, 0x002e)
                        print('O')
                        SetConsoleTextAttribute(console, 0x0000)
                        continue
                    }
                    when (t) {
                        '#' ->  SetConsoleTextAttribute(console, 0x002a)
                        '+' ->  SetConsoleTextAttribute(console, 0x0019)
                        '@' ->  SetConsoleTextAttribute(console, 0x004c)
                    }
                    print(t)
                    SetConsoleTextAttribute(console, 0x0000)
                }
            }
            print(t)
            SetConsoleTextAttribute(console, 0x0007)
            val c = alloc<COORD>().apply { X = 0; Y = HEI.toShort() }
            SetConsoleCursorPosition(console, c.readValue())
            print("Points: $points")
        }
    }

    private fun moveSnake() {
        when (dir) {
            Dir.NORTH -> head.Y--
            Dir.EAST  -> head.X++
            Dir.SOUTH -> head.Y++
            Dir.WEST  -> head.X--
        }
        val t = brd[head.X + WID * head.Y]
        if (t != NUL && t != '@') {
            alive = false
            return
        }
        brd[head.X + WID * head.Y] = '#'
        snk[headIdx].X = head.X
        snk[headIdx].Y = head.Y
        if (++headIdx >= MAX_LEN) headIdx = 0
        if (t == '@') {
            points++
            var x: Int
            var y: Int
            do {
                x = rand() % WID
                y = rand() % (HEI shr 1) + (HEI shr 1)
            }
            while (brd[x + WID * y] != NUL)
            brd[x + WID * y] = '@'
            return
        }
        SetConsoleCursorPosition(console, snk[tailIdx].readValue())
        print(' ')
        brd[snk[tailIdx].X + WID * snk[tailIdx].Y] = NUL
        if (++tailIdx >= MAX_LEN) tailIdx = 0
    }
}

fun main(args: Array<String>) {
    srand(time(null).toInt())
    Snake().play()
}


10 DEFINT A-Z
20 DIM F(32)
30 FOR I=2 TO 9999
40 F=0: N=I
50 IF N>0 AND (N AND 1)=0 THEN N=N\2: F(F)=2: F=F+1: GOTO 50
60 P=3
70 GOTO 100
80 IF N MOD P=0 THEN N=N\P: F(F)=P: F=F+1: GOTO 80
90 P=P+2
100 IF P<=N GOTO 80
110 IF F<=1 GOTO 190
120 N=I: S=0
130 IF N>0 THEN S=S+N MOD 10: N=N\10: GOTO 130
140 FOR J=0 TO F-1
150 N=F(J)
160 IF N>0 THEN S=S-N MOD 10: N=N\10: GOTO 160
170 NEXT
180 IF S=0 THEN PRINT USING " ####";I;: C=C+1
190 NEXT
200 PRINT
210 PRINT "Found";C;"Smith numbers."


class LinkedListNode
{
    public int Value { get; set; }
    public LinkedListNode Next { get; set; }

    // A constructor is not necessary, but could be useful.
    public Link(int value, LinkedListNode next = null)
    {
        Item = value;
        Next = next;
    }
}


struct link
{
  link* next;
  int data;
};


import StdMaybe

:: Link t = { next :: Maybe (Link t), data :: t }


(cons 1 (cons 2 (cons 3 nil))   => (1 2 3)


struct SLinkedNode(T) {
    T data;
    typeof(this)* next;
}

void main() {
    alias SLinkedNode!int N;
    N* n = new N(10);
}


UP, RIGHT, DOWN, LEFT = 1, 2, 3, 4
UpdateTime=0.200
Timer = 0
GridSize = 30
GridWidth, GridHeight = 20, 10

local directions = {
	[UP] = 	  {x= 0, y=-1},
	[RIGHT] = {x= 1, y= 0},
	[DOWN] =  {x= 0, y= 1},
	[LEFT] =  {x=-1, y= 0},
}

local function isPositionInBody(x, y)
	for i = 1, #Body-3, 2 do -- skip tail, it moves before we get in
		if x == Body[i] and y == Body[i+1] then
			return true
		end
	end
	return false
end

local function isPositionInApple(x, y)
	if x == Apple.x and y == Apple.y then
		return true
	end
	return false
end

local function newApple ()
	local ApplePlaced = false
	while not ApplePlaced do
		local x = GridSize*math.random (GridWidth)
		local y = GridSize*math.random (GridHeight)
		if not isPositionInBody(x, y) then
			Apple = {x=x, y=y}
			ApplePlaced = true
		end
	end
end

local function newGame ()
	Score = 0
	GameOver = false
	local x = GridSize*math.floor(math.random (0.25*GridWidth, 0.75*GridWidth))
	print (x)
	local y = GridSize*math.floor(math.random (0.25*GridHeight, 0.75*GridHeight))
	print (y)
	local iDirection = math.random(4)
	local d = directions[iDirection]
	Head = {
		x=x,
		y=y,
		iDirection = iDirection,
		nextDirection = iDirection,
	}
	Body = {x, y, x-GridSize*d.x, y-GridSize*d.y}
	Apples = {}
	newApple ()
end

function love.load()
	newGame ()
end

local function moveSnake (x, y, iDirection, longer)
	table.insert (Body, 1, x)
	table.insert (Body, 2, y)
	Head.x = x
	Head.y = y
	Head.iDirection = iDirection
	if not longer then
		-- remove last pair
		table.remove(Body)
		table.remove(Body)
	end
	if  x <= 0 or x > GridSize*(GridWidth) or
		y <= 0 or y > GridSize*(GridHeight) then
		GameOver = true
	end
end

function love.update(dt)
	Timer = Timer + dt
	if Timer < UpdateTime then return end
	Timer = Timer - UpdateTime

	local iDirection = Head.nextDirection
	local d = directions[iDirection]
	local x, y = Head.x+GridSize*d.x, Head.y+GridSize*d.y
	if isPositionInBody(x, y) then
		GameOver = true
	elseif isPositionInApple(x, y) then
		Score = Score + 1
		newApple ()
		moveSnake (x, y, iDirection, true)
	else
		moveSnake (x, y, iDirection, false)
	end
end

function drawHead () -- position, length, width and angle
	love.graphics.push()
	love.graphics.translate(Head.x, Head.y)
	love.graphics.rotate((Head.iDirection-2)*math.pi/2)
	love.graphics.polygon("fill",
		-GridSize/3, -GridSize /3,
		-GridSize/3,  GridSize /3,
		 GridSize/3, 0)
	love.graphics.pop()
end

function love.draw()
	love.graphics.setColor(0,1,0)
	love.graphics.print ('Score: '..tostring(Score), 10, 10)
	if GameOver then
		love.graphics.print ('Game Over: '..tostring(GameOver)..'. Press "Space" to continue', 10, 30)
	else
		love.graphics.translate(GridSize, GridSize)
		love.graphics.setColor(0.6,0.6,0.6)
		love.graphics.setLineWidth(0.25)
		for x = GridSize, GridSize*GridWidth, GridSize do
			love.graphics.line (x, GridSize, x, GridSize*GridHeight)
		end
		for y = GridSize, GridSize*GridHeight, GridSize do
			love.graphics.line (GridSize, y, GridSize*GridWidth, y)
		end
		love.graphics.setLineWidth((GridSize/4)+0.5)
		love.graphics.setColor(1,1,1)
		love.graphics.line (Body)
		drawHead ()
		love.graphics.setColor(1,0,0)
		love.graphics.circle ('fill', Apple.x, Apple.y, GridSize/4)
	end
end

function love.keypressed(key, scancode, isrepeat)
	if false then
	elseif key == "space" then
		if GameOver then
			GameOver = false
			newGame ()
		end
	elseif key == "escape" then
		love.event.quit()
	else
		local iDirection = Head.iDirection
		if iDirection == UP or
			iDirection == DOWN then
			local right = love.keyboard.isScancodeDown ("d")
			local left = love.keyboard.isScancodeDown ("a")
			if right and not left then
				iDirection = RIGHT
			elseif left and not right then
				iDirection = LEFT
			end
		else -- right or left
			local down = love.keyboard.isScancodeDown ("s")
			local up = love.keyboard.isScancodeDown ("w")
			if up and not down then
				iDirection = UP
			elseif down and not up then
				iDirection = DOWN
			end
		end
		Head.nextDirection = iDirection
	end
end


get "libhdr"

// Find the sum of the digits of N
let digsum(n) =
    n<10 -> n,
    n rem 10 + digsum(n/10)

// Factorize N
let factors(n, facs) = valof
$(  let count = 0 and fac = 3

    // Powers of 2
    while n>0 & (n & 1)=0
    $(  n := n >> 1
        facs!count := 2
        count := count + 1
    $)

    // Odd factors
    while fac <= n
    $(  while n rem fac=0
        $(  n := n / fac
            facs!count := fac
            count := count + 1
        $)
        fac := fac + 2
    $)

    resultis count
$)

// Is N a Smith number?
let smith(n) = valof
$(  let facs = vec 32
    let nfacs = factors(n, facs)
    let facsum = 0
    if nfacs<=1 resultis false   // primes are not Smith numbers
    for fac = 0 to nfacs-1 do
        facsum := facsum + digsum(facs!fac)
    resultis digsum(n) = facsum
$)

// Count and print Smith numbers below 10,000
let start() be
$(  let count = 0
    for i = 2 to 9999 if smith(i)
    $(  writed(i, 5)
        count := count + 1
        if count rem 16 = 0 then wrch('*N')
    $)
    writef("*NFound %N Smith numbers.*N", count)
$)


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

int numPrimeFactors(unsigned x) {
    unsigned p = 2;
    int pf = 0;
    if (x == 1)
        return 1;
    else {
        while (true) {
            if (!(x % p)) {
                pf++;
                x /= p;
                if (x == 1)
                    return pf;
            }
            else
                ++p;
        }
    }
}

void primeFactors(unsigned x, unsigned* arr) {
    unsigned p = 2;
    int pf = 0;
    if (x == 1)
        arr[pf] = 1;
    else {
        while (true) {
            if (!(x % p)) {
                arr[pf++] = p;
                x /= p;
                if (x == 1)
                    return;
            }
            else
                p++;
        }
    }
}

unsigned sumDigits(unsigned x) {
    unsigned sum = 0, y;
    while (x) {
        y = x % 10;
        sum += y;
        x /= 10;
    }
    return sum;
}

unsigned sumFactors(unsigned* arr, int size) {
    unsigned sum = 0;
    for (int a = 0; a < size; a++)
        sum += sumDigits(arr[a]);
    return sum;
}

void listAllSmithNumbers(unsigned x) {
    unsigned *arr;
    for (unsigned a = 4; a < x; a++) {
        int numfactors = numPrimeFactors(a);
        arr = (unsigned*)malloc(numfactors * sizeof(unsigned));
        if (numfactors < 2)
            continue;
        primeFactors(a, arr);
        if (sumDigits(a) == sumFactors(arr,numfactors))
            printf("%4u ",a);
        free(arr);
    }
}

int main(int argc, char* argv[]) {
    printf("All the Smith Numbers < 10000 are:\n");
    listAllSmithNumbers(10000);
    return 0;
}


Type
  pOneWayList = ^OneWayList;
  OneWayList = record
                pData : pointer ;
                Next  : pOneWayList ;
               end;


interface LinkedList guards LinkedListStamp {}
def empty implements LinkedListStamp {
    to null() { return true }
}
def makeLink(value :int, var next :LinkedList) {
    def link implements LinkedListStamp {
        to null() { return false }
        to value() { return value }
        to next() { return next }
        to setNext(new) { next := new }
    }
    return link
}


class Link
{
    prop int  Item;
    prop Link Next;

    constructor(int item, Link next)
    {
        Item := item;
        Next := next
    }
}


new( Data ) -> erlang:spawn( fun() -> loop( Data, nonext ) end ).


TUPLE: linked-list data next ;

: <linked-list> ( data -- linked-list )
    linked-list new swap >>data ;


import macros, os, random
import ncurses

when defined(Linux):
  proc positional_putch(x, y: int; ch: char) = mvaddch(x.cint, y.cint, ch.chtype)
  proc updateScreen = refresh()
  proc nonBlockingGetch(): char =
    let c = getch()
    result = if c in 0..255: char(c) else: '\0'
  proc closeScreen = endwin()

else:
  error "Not implemented"

const

  W = 80
  H = 40
  Space = 0
  Food = 1
  Border = 2
  Symbol = [' ', '@', '.']

type

  Dir {.pure.} = enum North, East, South, West
  Game = object
    board: array[W * H, int]
    head: int
    dir: Dir
    quit: bool

proc age(game: var Game) =
  ## Reduce a time-to-live, effectively erasing the tail.
  for i in 0..<W*H:
    if game.board[i] < 0: inc game.board[i]

proc plant(game: var Game) =
  ## Put a piece of food at random empty position.
  var r: int
  while true:
    r = rand(W * H - 1)
    if game.board[r] == Space: break
  game.board[r] = Food

proc start(game: var Game) =
  ## Initialize the board, plant a very first food item.
  for i in 0..<W:
    game.board[i] = Border
    game.board[i + (H - 1) * W] = Border
  for i in 0..<H:
    game.board[i * W] = Border
    game.board[i * W + W - 1] = Border
  game.head = W * (H - 1 - (H and 1)) shr 1   # Screen center for any H.
  game.board[game.head] = -5
  game.dir = North
  game.quit = false
  game.plant()

proc step(game: var Game) =
  let len = game.board[game.head]
  case game.dir
  of North: dec game.head, W
  of South: inc game.head, W
  of West: dec game.head
  of East: inc game.head

  case game.board[game.head]
  of Space:
    game.board[game.head] = len - 1  # Keep in mind "len" is negative.
    game.age()
  of Food:
    game.board[game.head] = len - 1
    game.plant()
  else:
    game.quit = true

proc show(game: Game) =
  for i in 0..<W*H:
    positionalPutch(i div W, i mod W, if game.board[i] < 0: '#' else: Symbol[game.board[i]])
  updateScreen()

var game: Game
randomize()
let win = initscr()
cbreak()              # Make sure thre is no buffering.
noecho()              # Suppress echoing of characters.
nodelay(win, true)    # Non-blocking mode.
game.start()

while not game.quit:
  game.show()
  case nonBlockingGetch()
  of 'i': game.dir = North
  of 'j': game.dir = West
  of 'k': game.dir = South
  of 'l': game.dir = East
  of 'q': game.quit = true
  else: discard
  game.step()
  os.sleep(300)       # Adjust here: 100 is very fast.

sleep(1000)
closeScreen()


(* A simple Snake Game *)
open Sdl

let width, height = (640, 480)

type pos = int * int

type game_state = {
  pos_snake: pos;
  seg_snake: pos list;
  dir_snake: [`left | `right | `up | `down];
  pos_fruit: pos;
  sleep_time: int;
  game_over: bool;
}

let red   = (255, 0, 0)
let blue  = (0, 0, 255)
let green = (0, 255, 0)
let black = (0, 0, 0)
let alpha = 255

let fill_rect renderer (x, y) =
  let rect = Rect.make4 x y 20 20 in
  Render.fill_rect renderer rect;
;;

let display_game renderer state =
  let bg_color, snake_color, fruit_color =
    if state.game_over
    then (red, black, green)
    else (black, blue, red)
  in
  Render.set_draw_color renderer bg_color alpha;
  Render.clear renderer;
  Render.set_draw_color renderer fruit_color alpha;
  fill_rect renderer state.pos_fruit;
  Render.set_draw_color renderer snake_color alpha;
  List.iter (fill_rect renderer) state.seg_snake;
  Render.render_present renderer;
;;

let proc_events dir_snake = function
  | Event.KeyDown { Event.keycode = Keycode.Left } -> `left
  | Event.KeyDown { Event.keycode = Keycode.Right } -> `right
  | Event.KeyDown { Event.keycode = Keycode.Up } -> `up
  | Event.KeyDown { Event.keycode = Keycode.Down } -> `down
  | Event.KeyDown { Event.keycode = Keycode.Q }
  | Event.KeyDown { Event.keycode = Keycode.Escape }
  | Event.Quit _ -> Sdl.quit (); exit 0
  | _ -> (dir_snake)

let rec event_loop dir_snake =
  match Event.poll_event () with
  | None -> (dir_snake)
  | Some ev ->
      let dir = proc_events dir_snake ev in
      event_loop dir

let rec pop = function
  | [_] -> []
  | hd :: tl -> hd :: (pop tl)
  | [] -> invalid_arg "pop"

let rec new_pos_fruit seg_snake =
  let new_pos =
    (20 * Random.int 32,
     20 * Random.int 24)
  in
  if List.mem new_pos seg_snake
  then new_pos_fruit seg_snake
  else (new_pos)

let update_state req_dir ({
    pos_snake;
    seg_snake;
    pos_fruit;
    dir_snake;
    sleep_time;
    game_over;
  } as state) =
  if game_over then state else
  let dir_snake =
    match dir_snake, req_dir with
    | `left, `right -> dir_snake
    | `right, `left -> dir_snake
    | `up, `down -> dir_snake
    | `down, `up -> dir_snake
    | _ -> req_dir
  in
  let pos_snake =
    let x, y = pos_snake in
    match dir_snake with
    | `left  -> (x - 20, y)
    | `right -> (x + 20, y)
    | `up    -> (x, y - 20)
    | `down  -> (x, y + 20)
  in
  let game_over =
    let x, y = pos_snake in
    List.mem pos_snake seg_snake
    || x < 0 || y < 0
    || x >= width
    || y >= height
  in
  let seg_snake = pos_snake :: seg_snake in
  let seg_snake, pos_fruit, sleep_time =
    if pos_snake = pos_fruit
    then (seg_snake, new_pos_fruit seg_snake, sleep_time - 1)
    else (pop seg_snake, pos_fruit, sleep_time)
  in
  { pos_snake;
    seg_snake;
    pos_fruit;
    dir_snake;
    sleep_time;
    game_over;
  }

let () =
  Random.self_init ();
  Sdl.init [`VIDEO];
  let window, renderer =
    Render.create_window_and_renderer ~width ~height ~flags:[]
  in
  Window.set_title ~window ~title:"Snake OCaml-SDL2";
  let initial_state = {
    pos_snake = (100, 100);
    seg_snake = [
      (100, 100);
      ( 80, 100);
      ( 60, 100);
    ];
    pos_fruit = (200, 200);
    dir_snake = `right;
    sleep_time = 120;
    game_over = false;
  } in

  let rec main_loop state =
    let req_dir = event_loop state.dir_snake in
    let state = update_state req_dir state in
    display_game renderer state;
    Timer.delay state.sleep_time;
    main_loop state
  in
  main_loop initial_state


using System;
using System.Collections.Generic;

namespace SmithNumbers {
    class Program {
        static int SumDigits(int n) {
            int sum = 0;
            while (n > 0) {
                n = Math.DivRem(n, 10, out int rem);
                sum += rem;
            }
            return sum;
        }

        static List<int> PrimeFactors(int n) {
            List<int> result = new List<int>();

            for (int i = 2; n % i == 0; n /= i) {
                result.Add(i);
            }

            for (int i = 3; i * i < n; i += 2) {
                while (n % i == 0) {
                    result.Add(i);
                    n /= i;
                }
            }

            if (n != 1) {
                result.Add(n);
            }

            return result;
        }

        static void Main(string[] args) {
            const int SIZE = 8;
            int count = 0;
            for (int n = 1; n < 10_000; n++) {
                var factors = PrimeFactors(n);
                if (factors.Count > 1) {
                    int sum = SumDigits(n);
                    foreach (var f in factors) {
                        sum -= SumDigits(f);
                    }
                    if (sum == 0) {
                        Console.Write("{0,5}", n);
                        if (count == SIZE - 1) {
                            Console.WriteLine();
                        }
                        count = (count + 1) % SIZE;
                    }
                }
            }
        }
    }
}


class Node
{
  const Int value  // keep value fixed
  Node? successor  // allow successor to change, also, can be 'null', for end of list

  new make (Int value, Node? successor := null)
  {
    this.value = value
    this.successor = successor
  }
}


0 value numbers
: push ( n -- )
  here swap numbers , , to numbers ;


type node
   real :: data
   type( node ), pointer :: next => null()
end type node
!
!. . . .
!
type( node ) :: head


type ll_int
    n as integer
    nxt as ll_int ptr
end type


type Ele struct {
    Data interface{}
    Next *Ele
}

func (e *Ele) Append(data interface{}) *Ele {
    if e.Next == nil {
        e.Next = &Ele{data, nil}
    } else {
        tmp := &Ele{data, e.Next}
        e.Next = tmp
    }
    return e.Next
}

func (e *Ele) String() string {
    return fmt.Sprintf("Ele: %v", e.Data)
}


use utf8;
use Time::HiRes qw(sleep);
use Term::ANSIColor qw(colored);
use Term::ReadKey qw(ReadMode ReadLine);

binmode(STDOUT, ':utf8');

use constant {
              VOID => 0,
              HEAD => 1,
              BODY => 2,
              TAIL => 3,
              FOOD => 4,
             };

use constant {
              LEFT  => [+0, -1],
              RIGHT => [+0, +1],
              UP    => [-1, +0],
              DOWN  => [+1, +0],
             };

use constant {
              BG_COLOR  => "on_black",
              SLEEP_SEC => 0.05,
             };

use constant {
              SNAKE_COLOR => ('bold green' . ' ' . BG_COLOR),
              FOOD_COLOR  => ('red'        . ' ' . BG_COLOR),
             };

use constant {
    U_HEAD => colored('▲', SNAKE_COLOR),
    D_HEAD => colored('▼', SNAKE_COLOR),
    L_HEAD => colored('◀', SNAKE_COLOR),
    R_HEAD => colored('▶', SNAKE_COLOR),

    U_BODY => colored('╹', SNAKE_COLOR),
    D_BODY => colored('╻', SNAKE_COLOR),
    L_BODY => colored('╴', SNAKE_COLOR),
    R_BODY => colored('╶', SNAKE_COLOR),

    U_TAIL => colored('╽', SNAKE_COLOR),
    D_TAIL => colored('╿', SNAKE_COLOR),
    L_TAIL => colored('╼', SNAKE_COLOR),
    R_TAIL => colored('╾', SNAKE_COLOR),

    A_VOID => colored(' ',   BG_COLOR),
    A_FOOD => colored('❇', FOOD_COLOR),
             };

local $| = 1;

my $w = eval { `tput cols` }  || 80;
my $h = eval { `tput lines` } || 24;
my $r = "\033[H";

my @grid = map {
    [map { [VOID] } 1 .. $w]
} 1 .. $h;

my $dir      = LEFT;
my @head_pos = ($h / 2, $w / 2);
my @tail_pos = ($head_pos[0], $head_pos[1] + 1);

$grid[$head_pos[0]][$head_pos[1]] = [HEAD, $dir];    # head
$grid[$tail_pos[0]][$tail_pos[1]] = [TAIL, $dir];    # tail

sub create_food {
    my ($food_x, $food_y);

    do {
        $food_x = rand($w);
        $food_y = rand($h);
    } while ($grid[$food_y][$food_x][0] != VOID);

    $grid[$food_y][$food_x][0] = FOOD;
}

create_food();

sub display {
    my $i = 0;

    print $r, join("\n",
        map {
            join("",
                map {
                    my $t = $_->[0];
                    if ($t != FOOD and $t != VOID) {
                        my $p = $_->[1];
                        $i =
                            $p eq UP   ? 0
                          : $p eq DOWN ? 1
                          : $p eq LEFT ? 2
                          :              3;
                    }
                        $t == HEAD ? (U_HEAD, D_HEAD, L_HEAD, R_HEAD)[$i]
                      : $t == BODY ? (U_BODY, D_BODY, L_BODY, R_BODY)[$i]
                      : $t == TAIL ? (U_TAIL, D_TAIL, L_TAIL, R_TAIL)[$i]
                      : $t == FOOD ? (A_FOOD)
                      :              (A_VOID);

                  } @{$_}
                )
          } @grid
    );
}

sub move {
    my $grew = 0;

    # Move the head
    {
        my ($y, $x) = @head_pos;

        my $new_y = ($y + $dir->[0]) % $h;
        my $new_x = ($x + $dir->[1]) % $w;

        my $cell = $grid[$new_y][$new_x];
        my $t    = $cell->[0];

        if ($t == BODY or $t == TAIL) {
            die "Game over!\n";
        }
        elsif ($t == FOOD) {
            create_food();
            $grew = 1;
        }

        # Create a new head
        $grid[$new_y][$new_x] = [HEAD, $dir];

        # Replace the current head with body
        $grid[$y][$x] = [BODY, $dir];

        # Save the position of the head
        @head_pos = ($new_y, $new_x);
    }

    # Move the tail
    if (not $grew) {
        my ($y, $x) = @tail_pos;

        my $pos   = $grid[$y][$x][1];
        my $new_y = ($y + $pos->[0]) % $h;
        my $new_x = ($x + $pos->[1]) % $w;

        $grid[$y][$x][0]         = VOID;    # erase the current tail
        $grid[$new_y][$new_x][0] = TAIL;    # create a new tail

        # Save the position of the tail
        @tail_pos = ($new_y, $new_x);
    }
}

ReadMode(3);
while (1) {
    my $key;
    until (defined($key = ReadLine(-1))) {
        move();
        display();
        sleep(SLEEP_SEC);
    }

    if    ($key eq "\e[A" and $dir ne DOWN ) { $dir = UP    }
    elsif ($key eq "\e[B" and $dir ne UP   ) { $dir = DOWN  }
    elsif ($key eq "\e[C" and $dir ne LEFT ) { $dir = RIGHT }
    elsif ($key eq "\e[D" and $dir ne RIGHT) { $dir = LEFT  }
}


#include <iostream>
#include <vector>
#include <iomanip>

void primeFactors( unsigned n, std::vector<unsigned>& r ) {
    int f = 2; if( n == 1 ) r.push_back( 1 );
    else {
        while( true ) {
            if( !( n % f ) ) {
                r.push_back( f );
                n /= f; if( n == 1 ) return;
            }
            else f++;
        }
    }
}
unsigned sumDigits( unsigned n ) {
    unsigned sum = 0, m;
    while( n ) {
        m = n % 10; sum += m;
        n -= m; n /= 10;
    }
    return sum;
}
unsigned sumDigits( std::vector<unsigned>& v ) {
    unsigned sum = 0;
    for( std::vector<unsigned>::iterator i = v.begin(); i != v.end(); i++ ) {
        sum += sumDigits( *i );
    }
    return sum;
}
void listAllSmithNumbers( unsigned n ) {
    std::vector<unsigned> pf;
    for( unsigned i = 4; i < n; i++ ) {
        primeFactors( i, pf ); if( pf.size() < 2 ) continue;
        if( sumDigits( i ) == sumDigits( pf ) )
            std::cout << std::setw( 4 ) << i << " ";
        pf.clear();
    }
    std::cout << "\n\n";
}
int main( int argc, char* argv[] ) {
    listAllSmithNumbers( 10000 );
    return 0;
}


class ListNode {
    Object payload
    ListNode next
    String toString() { "${payload} -> ${next}" }
}


class Link
{
    Link next;
    int data;
}


function LinkedList(value, next) {
    this._value = value;
    this._next = next;
}
LinkedList.prototype.value = function() {
    if (arguments.length == 1)
        this._value = arguments[0];
    else
        return this._value;
}
LinkedList.prototype.next = function() {
    if (arguments.length == 1)
        this._next = arguments[0];
    else
        return this._next;
}

// convenience function to assist the creation of linked lists.
function createLinkedListFromArray(ary) {
    var head = new LinkedList(ary[0], null);
    var prev = head;
    for (var i = 1; i < ary.length; i++) {
        var node = new LinkedList(ary[i], null);
        prev.next(node);
        prev = node;
    }
    return head;
}

var head = createLinkedListFromArray([10,20,30,40]);


constant W = 60, H = 30, MAX_LEN = 600
enum NORTH, EAST, SOUTH, WEST

sequence board, snake
bool alive
integer tailIdx, headIdx, hdX, hdY, d, points

procedure createField()
    clear_screen()
    board = repeat("+"&repeat(' ',W-2)&'+',H)
    for x=1 to W do
        board[1,x] = '+'
    end for
    board[H] = board[1]
    board[1+rand(H-2),1+rand(W-2)] = '@';
    snake = repeat(0,MAX_LEN)
    board[3,4] = '#'; tailIdx = 1; headIdx = 5;
    for c=tailIdx to headIdx do
        snake[c] = {3,3+c}
    end for
    {hdY,hdX} = snake[headIdx-1]; d = EAST; points = 0;
end procedure

procedure drawField()
    for y=1 to H do
        for x=1 to W do
            integer t = board[y,x]
            if t!=' ' then
                position(y,x)
                if x=hdX and y=hdY then
                    text_color(14); puts(1,'O');
                else
                    text_color({10,9,12}[find(t,"#[email protected]")]); puts(1,t);
                end if
            end if
        end for
    end for
    position(H+1,1); text_color(7); printf(1,"Points: %d",points)
end procedure

procedure readKey()
    integer k = find(get_key(),{333,331,328,336})
    if k then d = {EAST,WEST,NORTH,SOUTH}[k] end if
end procedure

procedure moveSnake()
integer x,y
    switch d do
        case NORTH: hdY -= 1
        case EAST:  hdX += 1
        case SOUTH: hdY += 1
        case WEST:  hdX -= 1
    end switch
    integer t = board[hdY,hdX];
    if t!=' ' and t!='@' then alive = false; return; end if
    board[hdY,hdX] = '#'; snake[headIdx] = {hdY,hdX};
    headIdx += 1; if headIdx>MAX_LEN then headIdx = 1 end if
    if t=='@' then
        points += 1
        while 1 do
            x = 1+rand(W-2); y = 1+rand(H-2);
            if board[y,x]=' ' then
                board[y,x] = '@'
                return
            end if
        end while
    end if
    {y,x} = snake[tailIdx]; position(y,x); puts(1,' '); board[y,x] = ' ';
    tailIdx += 1; if tailIdx>MAX_LEN then tailIdx = 1 end if
end procedure

procedure play()
    while true do
        createField(); alive = true; cursor(NO_CURSOR)
        while alive do drawField(); readKey(); moveSnake(); sleep(0.05) end while
        cursor(BLOCK_CURSOR); position(H+2,1); bk_color(0); text_color(11);
        puts(1,"Play again [Y/N]? ")
        if upper(wait_key())!='Y' then return end if
    end while
end procedure
play()


from __future__ import annotations

import itertools
import random

from enum import Enum

from typing import Any
from typing import Tuple

import pygame as pg

from pygame import Color
from pygame import Rect

from pygame.surface import Surface

from pygame.sprite import AbstractGroup
from pygame.sprite import Group
from pygame.sprite import RenderUpdates
from pygame.sprite import Sprite

class Direction(Enum):
    UP = (0, -1)
    DOWN = (0, 1)
    LEFT = (-1, 0)
    RIGHT = (1, 0)

    def opposite(self, other: Direction):
        return (self[0] + other[0], self[1] + other[1]) == (0, 0)

    def __getitem__(self, i: int):
        return self.value[i]

class SnakeHead(Sprite):
    def __init__(
        self,
        size: int,
        position: Tuple[int, int],
        facing: Direction,
        bounds: Rect,
    ) -> None:
        super().__init__()
        self.image = Surface((size, size))
        self.image.fill(Color("aquamarine4"))
        self.rect = self.image.get_rect()
        self.rect.center = position
        self.facing = facing
        self.size = size
        self.speed = size
        self.bounds = bounds

    def update(self, *args: Any, **kwargs: Any) -> None:
        # Move the snake in the direction it is facing.
        self.rect.move_ip(
            (
                self.facing[0] * self.speed,
                self.facing[1] * self.speed,
            )
        )

        # Move to the opposite side of the screen if the snake goes out of bounds.
        if self.rect.right > self.bounds.right:
            self.rect.left = 0
        elif self.rect.left < 0:
            self.rect.right = self.bounds.right

        if self.rect.bottom > self.bounds.bottom:
            self.rect.top = 0
        elif self.rect.top < 0:
            self.rect.bottom = self.bounds.bottom

    def change_direction(self, direction: Direction):
        if not self.facing == direction and not direction.opposite(self.facing):
            self.facing = direction

class SnakeBody(Sprite):
    def __init__(
        self,
        size: int,
        position: Tuple[int, int],
        colour: str = "white",
    ) -> None:
        super().__init__()
        self.image = Surface((size, size))
        self.image.fill(Color(colour))
        self.rect = self.image.get_rect()
        self.rect.center = position

class Snake(RenderUpdates):
    def __init__(self, game: Game) -> None:
        self.segment_size = game.segment_size
        self.colours = itertools.cycle(["aquamarine1", "aquamarine3"])

        self.head = SnakeHead(
            size=self.segment_size,
            position=game.rect.center,
            facing=Direction.RIGHT,
            bounds=game.rect,
        )

        neck = [
            SnakeBody(
                size=self.segment_size,
                position=game.rect.center,
                colour=next(self.colours),
            )
            for _ in range(2)
        ]

        super().__init__(*[self.head, *neck])

        self.body = Group()
        self.tail = neck[-1]

    def update(self, *args: Any, **kwargs: Any) -> None:
        self.head.update()

        # Snake body sprites don't update themselves. We update them here.
        segments = self.sprites()
        for i in range(len(segments) - 1, 0, -1):
            # Current sprite takes the position of the previous sprite.
            segments[i].rect.center = segments[i - 1].rect.center

    def change_direction(self, direction: Direction):
        self.head.change_direction(direction)

    def grow(self):
        tail = SnakeBody(
            size=self.segment_size,
            position=self.tail.rect.center,
            colour=next(self.colours),
        )
        self.tail = tail
        self.add(self.tail)
        self.body.add(self.tail)

class SnakeFood(Sprite):
    def __init__(self, game: Game, size: int, *groups: AbstractGroup) -> None:
        super().__init__(*groups)
        self.image = Surface((size, size))
        self.image.fill(Color("red"))
        self.rect = self.image.get_rect()

        self.rect.topleft = (
            random.randint(0, game.rect.width),
            random.randint(0, game.rect.height),
        )

        self.rect.clamp_ip(game.rect)

        # XXX: This approach to random food placement might end badly if the
        # snake is very large.
        while pg.sprite.spritecollideany(self, game.snake):
            self.rect.topleft = (
                random.randint(0, game.rect.width),
                random.randint(0, game.rect.height),
            )

            self.rect.clamp_ip(game.rect)

class Game:
    def __init__(self) -> None:
        self.rect = Rect(0, 0, 640, 480)
        self.background = Surface(self.rect.size)
        self.background.fill(Color("black"))

        self.score = 0
        self.framerate = 16

        self.segment_size = 10
        self.snake = Snake(self)
        self.food_group = RenderUpdates(SnakeFood(game=self, size=self.segment_size))

        pg.init()

    def _init_display(self) -> Surface:
        bestdepth = pg.display.mode_ok(self.rect.size, 0, 32)
        screen = pg.display.set_mode(self.rect.size, 0, bestdepth)

        pg.display.set_caption("Snake")
        pg.mouse.set_visible(False)

        screen.blit(self.background, (0, 0))
        pg.display.flip()

        return screen

    def draw(self, screen: Surface):
        dirty = self.snake.draw(screen)
        pg.display.update(dirty)

        dirty = self.food_group.draw(screen)
        pg.display.update(dirty)

    def update(self, screen):
        self.food_group.clear(screen, self.background)
        self.food_group.update()
        self.snake.clear(screen, self.background)
        self.snake.update()

    def main(self) -> int:
        screen = self._init_display()
        clock = pg.time.Clock()

        while self.snake.head.alive():
            for event in pg.event.get():
                if event.type == pg.QUIT or (
                    event.type == pg.KEYDOWN and event.key in (pg.K_ESCAPE, pg.K_q)
                ):
                    return self.score

            # Change direction using the arrow keys.
            keystate = pg.key.get_pressed()

            if keystate[pg.K_RIGHT]:
                self.snake.change_direction(Direction.RIGHT)
            elif keystate[pg.K_LEFT]:
                self.snake.change_direction(Direction.LEFT)
            elif keystate[pg.K_UP]:
                self.snake.change_direction(Direction.UP)
            elif keystate[pg.K_DOWN]:
                self.snake.change_direction(Direction.DOWN)

            # Detect collisions after update.
            self.update(screen)

            # Snake eats food.
            for food in pg.sprite.spritecollide(
                self.snake.head, self.food_group, dokill=False
            ):
                food.kill()
                self.snake.grow()
                self.score += 1

                # Increase framerate to speed up gameplay.
                if self.score % 5 == 0:
                    self.framerate += 1

                self.food_group.add(SnakeFood(self, self.segment_size))

            # Snake hit its own tail.
            if pg.sprite.spritecollideany(self.snake.head, self.snake.body):
                self.snake.head.kill()

            self.draw(screen)
            clock.tick(self.framerate)

        return self.score

if __name__ == "__main__":
    game = Game()
    score = game.main()
    print(score)


(defn divisible? [a b]
  (zero? (mod a b)))

(defn prime? [n]
  (and (> n 1) (not-any? (partial divisible? n) (range 2 n))))

(defn prime-factors
  ([n] (prime-factors n 2 '()))
  ([n candidate acc]
    (cond
      (<= n 1) (reverse acc)
      (zero? (rem n candidate)) (recur
                                  (/ n candidate)
                                  candidate
                                  (cons candidate acc))
      :else (recur n (inc candidate) acc))))

(defn sum-digits [n]
  (reduce + (map #(- (int %) (int \0)) (str n))))

(defn smith-number? [n]
  (and (not (prime? n))
       (= (sum-digits n)
          (sum-digits (clojure.string/join "" (prime-factors n))))))

(filter smith-number? (range 1 10000))


abstract type AbstractNode{T} end

struct EmptyNode{T} <: AbstractNode{T} end
mutable struct Node{T} <: AbstractNode{T}
    data::T
    next::AbstractNode{T}
end
Node{T}(x) where T = Node{T}(x::T, EmptyNode{T}())

mutable struct LinkedList{T}
    head::AbstractNode{T}
end
LinkedList{T}() where T = LinkedList{T}(EmptyNode{T}())
LinkedList() = LinkedList{Any}()

Base.isempty(ll::LinkedList) = ll.head isa EmptyNode
function lastnode(ll::LinkedList)
    if isempty(ll) throw(BoundsError()) end
    nd = ll.head
    while !(nd.next isa EmptyNode)
        nd = nd.next
    end
    return nd
end

function Base.push!(ll::LinkedList{T}, x::T) where T
    nd = Node{T}(x)
    if isempty(ll)
        ll.head = nd
    else
        tail = lastnode(ll)
        tail.next = nd
    end
    return ll
end
function Base.pop!(ll::LinkedList{T}) where T
    if isempty(ll)
        throw(ArgumentError("list must be non-empty"))
    elseif ll.head.next isa EmptyNode
        nd = ll.head
        ll.head = EmptyNode{T}()
    else
        nx = ll.head
        while !isa(nx.next.next, EmptyNode)
            nx = nx.next
        end
        nd = nx.next
        nx.next = EmptyNode{T}()
    end
    return nd.data
end

lst = LinkedList{Int}()
push!(lst, 1)
push!(lst, 2)
push!(lst, 3)
pop!(lst) # 3
pop!(lst) # 2
pop!(lst) # 1


// version 1.1.2

class Node<T: Number>(var data: T, var next: Node<T>? = null) {
    override fun toString(): String {
        val sb = StringBuilder(this.data.toString())
        var node = this.next
        while (node != null) {
            sb.append(" -> ", node.data.toString())
            node = node.next
        }
        return sb.toString()
    }
}

fun main(args: Array<String>) {
    val n = Node(1, Node(2, Node(3)))
    println(n)
}


fput item list ; add item to the head of a list

first list  ; get the data
butfirst list ; get the remainder
bf list       ; contraction for "butfirst"


use SDL2::Raw;
use Cairo;

constant W = 1280;
constant H = 960;

constant FIELDW = W div 32;
constant FIELDH = H div 32;

SDL_Init(VIDEO);

my $window = SDL_CreateWindow(
    'Snake',
    SDL_WINDOWPOS_CENTERED_MASK,
    SDL_WINDOWPOS_CENTERED_MASK,
    W, H,
    OPENGL
);

my $render = SDL_CreateRenderer($window, -1, ACCELERATED +| PRESENTVSYNC);

my $snake_image = Cairo::Image.record(
    -> $_ {
        .save;
        .rectangle: 0, 0, 64, 64;
        .clip;
        .rgb: 0, 1, 0;
        .rectangle: 0, 0, 64, 64;
        .fill :preserve;
        .rgb: 0, 0, 0;
        .stroke;
        .restore;

        .save;
        .translate: 64, 0;
        .rectangle: 0, 0, 64, 64;
        .clip;
        .rgb: 1, 0, 0;
        .arc: 32, 32, 30, 0, 2 * pi;
        .fill :preserve;
        .rgb: 0, 0, 0;
        .stroke;
        .restore;
    }, 128, 128, Cairo::FORMAT_ARGB32);

my $snake_texture = SDL_CreateTexture(
    $render,
    %PIXELFORMAT<ARGB8888>,
    STATIC,
    128,
    128
);

SDL_UpdateTexture(
    $snake_texture,
    SDL_Rect.new(
        :x(0),
        :y(0),
        :w(128),
        :h(128)
    ),
    $snake_image.data,
    $snake_image.stride // 128 * 4
);

SDL_SetTextureBlendMode($snake_texture, 1);

SDL_SetRenderDrawBlendMode($render, 1);

my $snakepiece_srcrect = SDL_Rect.new(:w(64), :h(64));
my $nompiece_srcrect   = SDL_Rect.new(:w(64), :h(64), :x(64));

my $event = SDL_Event.new;

enum GAME_KEYS (
    K_UP    => 82,
    K_DOWN  => 81,
    K_LEFT  => 80,
    K_RIGHT => 79,
);

my Complex @snakepieces = 10+10i;
my Complex @noms;
my Complex $snakedir = 1+0i;
my $nomspawn   = 0;
my $snakespeed = 0.1;
my $snakestep  = 0;
my $nom        = 4;

my $last_frame_start = now;
main: loop {
    my $start = now;
    my $dt = $start - $last_frame_start // 0.00001;
    while SDL_PollEvent($event) {
        my $casted_event = SDL_CastEvent($event);
        given $casted_event {
            when *.type == QUIT    { last main }
            when *.type == KEYDOWN {
                if GAME_KEYS(.scancode) -> $comm {
                    given $comm {
                        when 'K_LEFT'  { $snakedir = -1+0i unless $snakedir ==  1+0i }
                        when 'K_RIGHT' { $snakedir =  1+0i unless $snakedir == -1+0i }
                        when 'K_UP'    { $snakedir =  0-1i unless $snakedir ==  0+1i }
                        when 'K_DOWN'  { $snakedir =  0+1i unless $snakedir ==  0-1i }
                    }
                }
            }
        }
    }

    if ($nomspawn -= $dt) < 0 {
        $nomspawn += 1;
        @noms.push: (^FIELDW).pick + (^FIELDH).pick * i unless @noms > 3;
        @noms.pop if @noms[*-1] == any(@snakepieces);
    }

    if ($snakestep -= $dt) < 0 {
        $snakestep += $snakespeed;

        @snakepieces.unshift: do given @snakepieces[0] {
            ($_.re + $snakedir.re) % FIELDW
            + (($_.im + $snakedir.im) % FIELDH) * i
        }

        if @snakepieces[2..*].first( * == @snakepieces[0], :k ) -> $idx {
            @snakepieces = @snakepieces[0..($idx + 1)];
        }

        @noms .= grep(
            { $^piece == @snakepieces[0] ?? ($nom += 1) && False !! True }
        );

        if $nom == 0 {
            @snakepieces.pop;
        } else {
            $nom = $nom - 1;
        }
    }

    for @snakepieces {
        SDL_SetTextureColorMod(
            $snake_texture,
            255,
            (cos((++$) / 2) * 100 + 155).round,
            255
        );

        SDL_RenderCopy(
            $render,
            $snake_texture,
            $snakepiece_srcrect,
            SDL_Rect.new(.re * 32, .im * 32, 32, 32)
        );
    }

    SDL_SetTextureColorMod($snake_texture, 255, 255, 255);

    for @noms {
        SDL_RenderCopy(
            $render,
            $snake_texture,
            $nompiece_srcrect,
            SDL_Rect.new(.re * 32, .im * 32, 32, 32)
        )
    }

    SDL_RenderPresent($render);
    SDL_SetRenderDrawColor($render, 0, 0, 0, 0);
    SDL_RenderClear($render);

    $last_frame_start = $start;
    sleep(1 / 50);
}

SDL_Quit();


% Get all digits of a number
digits = iter (n: int) yields (int)
    while n > 0 do
        yield(n // 10)
        n := n / 10
    end
end digits

% Get all prime factors of a number
prime_factors = iter (n: int) yields (int)
    % Take factors of 2 out first (the compiler should optimize)
    while n // 2 = 0 do yield(2) n := n/2 end

    % Next try odd factors
    fac: int := 3
    while fac <= n do
        while n // fac = 0 do
            yield(fac)
            n := n/fac
        end
        fac := fac + 2
    end
end prime_factors

% See if a number is a Smith number
smith = proc (n: int) returns (bool)
    dsum: int := 0
    fac_dsum: int := 0

    % Find the sum of the digits
    for d: int in digits(n) do dsum := dsum + d end

    % Find the sum of the digits of all factors
    nfac: int := 0
    for fac: int in prime_factors(n) do
        nfac := nfac + 1
        for d: int in digits(fac) do fac_dsum := fac_dsum + d end
    end

    % The number is a Smith number if these two are equal,
    % and the number is not prime (has more than one factor)
    return(fac_dsum = dsum cand nfac > 1)
end smith

% Yield all Smith numbers up to a limit
smiths = iter (max: int) yields (int)
    for i: int in int$from_to(1, max-1) do
        if smith(i) then yield(i) end
    end
end smiths

% Display all Smith numbers below 10,000
start_up = proc ()
    po: stream := stream$primary_output()
    count: int := 0
    for s: int in smiths(10000) do
        stream$putright(po, int$unparse(s), 5)
        count := count + 1
        if count // 16 = 0 then stream$putl(po, "") end
    end
    stream$putl(po, "\nFound " || int$unparse(count) || " Smith numbers.")
end start_up


include "cowgol.coh";
typedef N is uint16;   # 16-bit math is good enough

# Print a value right-justified in a field of length N
sub print_right(n: N, width: uint8) is
    var arr: uint8[16];
    var buf := &arr[0];
    var nxt := UIToA(n as uint32, 10, buf);
    var len := (nxt - buf) as uint8;
    while len < width loop
        print_char(' ');
        len := len + 1;
    end loop;
    print(buf);
end sub;

# Find the sum of the digits of a number
sub digit_sum(n: N): (sum: N) is
    sum := 0;
    while n > 0 loop
        sum := sum + n % 10;
        n := n / 10;
    end loop;
end sub;

# Factorize a number, write the factors into the buffer,
# return the amount of factors.
sub factorize(n: N, buf: [N]): (count: N) is
    count := 0;
    # Take care of the factors of 2 first
    while n>0 and n & 1 == 0 loop
        n := n >> 1;
        count := count + 1;
        [buf] := 2;
        buf := @next buf;
    end loop;
    # Then do the odd factors
    var fac: N := 3;
    while n >= fac loop
        while n % fac == 0 loop
            n := n / fac;
            count := count + 1;
            [buf] := fac;
            buf := @next buf;
        end loop;
        fac := fac + 2;
    end loop;
end sub;

# See if a number is a Smith number
sub smith(n: N): (rslt: uint8) is
    rslt := 0;
    var facs: N[16];
    var n_facs := factorize(n, &facs[0]) as @indexof facs;
    if n_facs > 1 then
        # Only composite numbers are Smith numbers
        var dsum := digit_sum(n);
        var facsum: N := 0;
        var i: @indexof facs := 0;
        while i < n_facs loop
            facsum := facsum + digit_sum(facs[i]);
            i := i + 1;
        end loop;
        if facsum == dsum then rslt := 1; end if;
    end if;
end sub;

# Display all Smith numbers below 10000
var i: N := 2;
var count: N := 0;
while i < 10000 loop
    if smith(i) != 0 then
        count := count + 1;
        print_right(i, 5);
        if count & 0xF == 0 then print_nl(); end if;
    end if;
    i := i + 1;
end loop;
print_nl();
print("Found ");
print_i32(count as uint32);
print(" Smith numbers.\n");


import std.stdio;

void main() {
    int cnt;
    for (int n=1; n<10_000; n++) {
        auto factors = primeFactors(n);
        if (factors.length > 1) {
            int sum = sumDigits(n);
            foreach (f; factors) {
                sum -= sumDigits(f);
            }
            if (sum==0) {
                writef("%4s  ", n);
                cnt++;
            }
            if (cnt==10) {
                cnt = 0;
                writeln();
            }
        }
    }
}

auto primeFactors(int n) {
    import std.array : appender;
    auto result = appender!(int[]);

    for (int i=2; n%i==0; n/=i) {
        result.put(i);
    }

    for (int i=3; i*i<=n; i+=2) {
        while (n%i==0) {
            result.put(i);
            n/=i;
        }
    }

    if (n!=1) {
        result.put(n);
    }

    return result.data;
}

int sumDigits(int n) {
    int sum;
    while (n > 0) {
        sum += (n%10);
        n /= 10;
    }
    return sum;
}


TYPE
  Link = POINTER TO LinkRcd;
  LinkRcd = RECORD
    Next: Link;
    Data: INTEGER
  END;


TYPE
  Link = REF LinkRcd;
  LinkRcd = RECORD
    Next: Link;
    Data: INTEGER
  END;


class link
        declare data
        declare next
end


type

  Node[T] = ref object
    next: Node[T]
    data: T

  SinglyLinkedList[T] = object
    head, tail: Node[T]

proc newNode[T](data: T): Node[T] =
  Node[T](data: data)

proc append[T](list: var SinglyLinkedList[T]; node: Node[T]) =
  if list.head.isNil:
    list.head = node
    list.tail = node
  else:
    list.tail.next = node
    list.tail = node

proc append[T](list: var SinglyLinkedList[T]; data: T) =
  list.append newNode(data)

proc prepend[T](list: var SinglyLinkedList[T]; node: Node[T]) =
  if list.head.isNil:
    list.head = node
    list.tail = node
  else:
    node.next = list.head
    list.head = node

proc prepend[T](list: var SinglyLinkedList[T]; data: T) =
  list.prepend newNode(data)

proc `$`[T](list: SinglyLinkedList[T]): string =
  var s: seq[T]
  var n = list.head
  while not n.isNil:
    s.add n.data
    n = n.next
  result = s.join(" → ")

var list: SinglyLinkedList[int]

for i in 1..5: list.append(i)
for i in 6..10: list.prepend(i)
echo "List: ", list


#import <Foundation/Foundation.h>

@interface RCListElement<T> : NSObject
{
  RCListElement<T> *next;
  T datum;
}
- (RCListElement<T> *)next;
- (T)datum;
- (RCListElement<T> *)setNext: (RCListElement<T> *)nx;
- (void)setDatum: (T)d;
@end

@implementation RCListElement
- (RCListElement *)next
{
  return next;
}
- (id)datum
{
  return datum;
}
- (RCListElement *)setNext: (RCListElement *)nx
{
  RCListElement *p = next;
  next = nx;
  return p;
}
- (void)setDatum: (id)d
{
  datum = d;
}
@end


type 'a list = Nil | Cons  of 'a * 'a list


/* add to file Cargo.toml:
[dependencies]
winsafe = "0.0.8"
rand = "0.8.4"
*/

#![windows_subsystem = "windows"]

use rand::Rng;
use std::{cell::RefCell, rc::Rc};
use winsafe::{co, gui, prelude::*, COLORREF, HBRUSH, HPEN, SIZE};

const STEP: i32 = 3; // px, motion per frame. STEP and FPS determine the smoothness and speed of the animation.
const FPS: u32 = 90;
const CELL: i32 = 21; // px, game grid (logical step). Will be aligned by STEP
const FIELD_W: i32 = 20; // width of the square field in CELLs
const SNAKE_W: i32 = 20; // px
const ROUNDING: SIZE = SIZE::new(SNAKE_W / 2, SNAKE_W / 2);

const RATIO: i32 = CELL / STEP;
const START_CELL: i32 = FIELD_W / 2 * RATIO;
/// total field width (with overlap for collisions) in STEPs
const TW: i32 = (FIELD_W + 2) * RATIO;
#[derive(Clone, Copy)]
#[repr(i32)]
enum Direction {
    Start = 0,
    A = -1,
    D = 1,
    W = -TW,
    S = TW,
}
use Direction::*;

struct Context {
    wnd: gui::WindowMain,
    snake: Vec<i32>, // [ids_rect] where id_rect = y * TW + x (where x, y: nSTEPs)
    id_r: [i32; 6],  // ID 6 rectangles to color in next frame (bg, tail, turn, body, food, head)
    gap: i32,        // gap in STEPs between animation and logic cell (negative - remove tail)
    dir: Direction,
    ordered_dir: Direction,
}
impl Context {
    fn new(wnd: gui::WindowMain, len: usize) -> Self {
        Self {
            wnd,
            snake: vec![START_CELL; len.saturating_sub(RATIO as usize)],
            id_r: [START_CELL; 6],
            gap: 0,
            dir: Start,
            ordered_dir: S,
        }
    }
}

pub fn main() {
    let [bg, tail, turn, body, food, head] = [0usize, 1, 2, 3, 4, 5];
    let mut colors = [(0x00, 0xF0, 0xA0); 6]; // color tail, turn, body
    colors[bg] = (0x00, 0x50, 0x90);
    colors[food] = (0xFF, 0x50, 0x00);
    colors[head] = (0xFF, 0xFF, 0x00);
    let brushes = COLORREF::new_array(&colors).map(|c| HBRUSH::CreateSolidBrush(c).unwrap());

    let wnd = gui::WindowMain::new(gui::WindowMainOpts {
        title: "Snake - Start: Space, then press W-A-S-D".to_string(),
        size: winsafe::SIZE::new(FIELD_W * RATIO * STEP, FIELD_W * RATIO * STEP),
        ex_style: co::WS_EX::CLIENTEDGE,
        class_bg_brush: brushes[bg],
        ..Default::default()
    });

    let context = Rc::new(RefCell::new(Context::new(wnd.clone(), 0)));

    wnd.on().wm_key_down({
        let context = Rc::clone(&context);
        move |k| {
            let mut ctx = context.borrow_mut();
            match (ctx.dir, k.char_code as u8) {
                (Start, bt @ (b' ' | 113)) => {
                    let len = ctx.snake.len(); //                              113 == F2 key
                    *ctx = Context::new(ctx.wnd.clone(), if bt == b' ' { len } else { 0 });
                    ctx.wnd.hwnd().InvalidateRect(None, true)?; // call .wm_paint() with erase
                    ctx.wnd.hwnd().SetTimer(1, 1000 / FPS, None)?;
                }
                (W | S, bt @ (b'A' | b'D')) => ctx.ordered_dir = if bt == b'A' { A } else { D },
                (A | D, bt @ (b'S' | b'W')) => ctx.ordered_dir = if bt == b'S' { S } else { W },
                _ => (),
            }
            Ok(())
        }
    });

    wnd.on().wm_timer(1, {
        let context = Rc::clone(&context);
        let cells: Vec<i32> = (1..=FIELD_W)
            .flat_map(|y| (1..=FIELD_W).map(move |x| (y * TW + x) * RATIO))
            .collect();
        move || {
            let mut ctx = context.borrow_mut();
            let new_h = ctx.id_r[head] + ctx.dir as i32;
            ctx.id_r[body] = ctx.id_r[head];
            ctx.id_r[head] = new_h;
            if ctx.gap < 0 {
                ctx.id_r[bg] = ctx.snake.remove(0);
                ctx.id_r[tail] = ctx.snake[0];
                ctx.id_r[turn] = ctx.snake[RATIO as usize / 2];
            }
            ctx.gap -= ctx.gap.signum();
            if ctx.gap == 0 {
                ctx.dir = ctx.ordered_dir;
                let hw = ctx.wnd.hwnd();
                let eat = new_h == ctx.id_r[food];
                if !eat && (cells.binary_search(&new_h).is_err() || ctx.snake.contains(&&new_h)) {
                    hw.KillTimer(1)?;
                    hw.SetWindowText(&(hw.GetWindowText()? + "  Restart: F2 (with save - Space)"))?;
                    ctx.dir = Start;
                    return Ok(());
                } else if eat || ctx.id_r[food] == 0 && ctx.id_r[tail] != START_CELL {
                    let mut snk_cells: Vec<_> = ctx.snake.iter().step_by(RATIO as usize).collect();
                    if eat && snk_cells.len() == cells.len() - 2 {
                        hw.SetWindowText(&format!("Snake - EATEN ALL: {} !!!", snk_cells.len()))?
                    } else if eat {
                        hw.SetWindowText(&format!("Snake - Eaten: {}.", snk_cells.len()))?
                    }
                    if ctx.id_r[tail] == START_CELL || eat && snk_cells.len() == cells.len() - 2 {
                        ctx.id_r[food] = 0; // hide food if not all of the saved snake has come out or everything is eaten
                    } else if snk_cells.len() + 1 < cells.len() {
                        snk_cells.sort();
                        ctx.id_r[food] = *(cells.iter())
                            .filter(|i| **i != new_h && snk_cells.binary_search(i).is_err())
                            .nth(rand::thread_rng().gen_range(0..cells.len() - snk_cells.len() - 1))
                            .unwrap();
                    }
                }
                ctx.gap = if eat { RATIO } else { -RATIO }
            }
            ctx.snake.push(new_h);
            ctx.wnd.hwnd().InvalidateRect(None, false)?; // call .wm_paint() without erase
            Ok(())
        }
    });

    wnd.on().wm_paint(move || {
        let ctx = context.borrow();
        let mut ps = winsafe::PAINTSTRUCT::default();
        let hdc = ctx.wnd.hwnd().BeginPaint(&mut ps)?;
        hdc.SelectObjectPen(HPEN::CreatePen(co::PS::NULL, 0, COLORREF::new(0, 0, 0))?)?;
        for (&id_rect, &brush) in ctx.id_r.iter().zip(&brushes) {
            hdc.SelectObjectBrush(brush)?;
            let left = id_rect % TW * STEP - (STEP * RATIO + SNAKE_W) / 2;
            let top = id_rect / TW * STEP - (STEP * RATIO + SNAKE_W) / 2;
            hdc.RoundRect(
                winsafe::RECT {
                    left,
                    top,
                    right: left + SNAKE_W,
                    bottom: top + SNAKE_W,
                },
                ROUNDING,
            )?;
        }
        ctx.wnd.hwnd().EndPaint(&ps);
        Ok(())
    });

    if let Err(e) = wnd.run_main(None) {
        winsafe::HWND::NULL
            .MessageBox(&e.to_string(), "Uncaught error", co::MB::ICONERROR)
            .unwrap();
    }
}


V seconds = Float(input())
print(‘Sleeping...’)
sleep(seconds)
print(‘Awake!’)


/* Find the sum of the digits of a number */
proc nonrec digitsum(word n) word:
    word sum;
    sum := 0;
    while n ~= 0 do
        sum := sum + n % 10;
        n := n / 10
    od;
    sum
corp

/* Find all prime factors and write them into the given array
   (which is assumed to be big enough); return the amount of
   factors. */
proc nonrec factors(word n; [*] word facs) word:
    word count, fac;
    count := 0;

    /* take out factors of 2 */
    while n > 0 and n & 1 = 0 do
        n := n >> 1;
        facs[count] := 2;
        count := count + 1
    od;

    /* take out odd factors */
    fac := 3;
    while n >= fac do
        while n % fac = 0 do
            n := n / fac;
            facs[count] := fac;
            count := count + 1;
        od;
        fac := fac + 2
    od;
    count
corp

/* See if a number is a Smith number */
proc nonrec smith(word n) bool:
    [32] word facs;   /* 32 factors ought to be enough for everyone */
    word dsum, facsum, nfacs, i;

    nfacs := factors(n, facs);
    if nfacs = 1 then
        false  /* primes are not Smith numbers */
    else
        dsum := digitsum(n);
        facsum := 0;
        for i from 0 upto nfacs-1 do
            facsum := facsum + digitsum(facs[i])
        od;
        dsum = facsum
    fi
corp

/* Find all Smith numbers below 10000 */
proc nonrec main() void:
    word i, count;
    count := 0;
    for i from 2 upto 9999 do
        if smith(i) then
            write(i:5);
            count := count + 1;
            if count & 0xF = 0 then writeln() fi
        fi
    od;
    writeln();
    writeln("Found ", count, " Smith numbers.")
corp