#!raku

# Given a matrix of m x n elements (m rows, n columns),
# return all elements of the matrix in spiral order.
#
# Example 1:
# Input:
# [[ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ]]
# Output:
# [1, 2, 3, 6, 9, 8, 7, 4, 5]
#
# Example 2:
# Input:
# [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
# Output:
# [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]

enum Dir ;

class Cur {
  has Int $.row is rw = 0;
  has Int $.col is rw = 0;
  has Dir $.dir is rw = Dir::Right;

  has $!d = ((0, 1), (1, 0), (0, -1), (-1, 0));

  method next {
    $.dir = self.next-dir($.dir);
    $.row += $!d[$.dir][0];
    $.col += $!d[$.dir][1];
  }

  method same-dir(:@a, --> Bool) {
    if @a[$.row + $!d[$.dir][0]][$.col + $!d[$.dir][1]] {
      $.row += $!d[$.dir][0];
      $.col += $!d[$.dir][1];
      True;
    } else {
      False;
    }
  }

  method next-dir(Dir $dir) {
    given $dir {
      when Dir::Right { Dir::Down }
      when Dir::Down { Dir::Left }
      when Dir::Left { Dir::Up }
      when Dir::Up { Dir::Right }
    }
  }
}

class Spiral {
  has @!a;
  has @.b of Int is rw;
  has Cur $!c;

  submethod BUILD(:@!a) {
    $!c = Cur.new;
    my $e = @!a.flatmap(|*).elems;

    while @!b.elems != $e {
      if @!a[$!c.row][$!c.col] {
        @!b.push(@!a[$!c.row][$!c.col]);
        @!a[$!c.row][$!c.col] = 0;
        $!c.next unless $!c.same-dir(:@!a);
      } else {
        $!c.next;
      }
    }
  }
}

use Test;

my @a = (1..9).Array.rotor(3);
ok Spiral.new(:@a).b == [1, 2, 3, 6, 9, 8, 7, 4, 5];

@a = (1..12).Array.rotor(3);
ok Spiral.new(:@a).b == [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7];

   Page Updates
Customize New Linux Install
Cisco CCNA Study :: Home Lab Notes
PostgreSQL Backup Script
Generate new Factorio map
Install and setup snmpd on RedHat Enterprise Linux
   Recent Articles
Debug a Linux Kernel in QEMU
Install xfce4 on Debian
Console Blackjack in Perl
Selenium::WebDriver::Error::UnknownError
Game of Life in C++ using the SDL2
   Tags
active-record (2) android (1) apache (1) apt (1) arcade (1) awk (2) backup (1) bash (2) bashrc (1) battleship (1) bdd (1) blackjack (12) book (1) books (1) build (1) c (2) c++ (2) cacti (1) calculator (1) capybara (1) ccna (1) cisco (1) clang (1) clang++ (1) console (5) cpp (2) crm (1) crystal (1) data (1) database (1) debian (7) diff (1) elixir (1) factorio (2) fedora (1) firewall (1) freebsd (1) g++ (1) game (4) games (1) gcc (1) gem (1) git (3) github (1) gmail (1) go-lang (3) google-chrome (1) haml (1) home (1) infix (1) ipv4 (1) irssi (1) kernel (4) lab (1) latin1 (1) life (1) linux (7) lottery (1) matrix (1) meta (1) microsoft (1) moarvm (1) model (1) module (1) mongodb (1) mp3s (1) mutt (1) nautical (1) nqp (1) object (1) oidentd (1) operator (1) orm (2) pairing (1) pair-programming (1) patch (1) perl (1) pigpen (1) postgresql (3) powerball (1) programming (1) psql (1) python (2) python3 (1) qemu (1) raku (16) raspberry-pi (1) raspberrypi (1) reactjs (2) readline (1) retropie (1) reversi (1) rhel (1) ruby (1) sdl2 (4) sed (1) selenium (1) selinux (1) snmpd (1) split (1) ssh (1) stack (1) subnet (1) systemd (1) template (1) test (1) testing (3) tictactoe (1) trace (1) typescript (2) ubuntu (2) utf8 (1) virus (1) war (1) xargs (1) xfce4 (1) xvfb (1) zef (1) zsh (1)

Copyright © 2005 - 2021

GregDonald.com · Contact · EUGOR · Nautical War · CRM12

All Rights Reserved