HackerRank 30 Days of Code: Day 11: 2D Arrays

Не Литкодом единым, как говорится! Нашёл на диске пару задачек с HackerRank — видимо, показались тогда особо любопытными, и были сохранены.

Впрочем, и сейчас они выглядят интересно. Эта, например (первая из них) — перемещение паттерна в виде «песочных часов» по «игровому полю», представленному матрицей, с целью найти такой паттерн, сумма цифр в котором будет максимальной.

Здесь у меня получилось два решения — частное (на Java) и общее (на Perl).

Java-решение

Решение для паттерна и поля, указанных в задаче. Т.е. поле размером 6х6 и часики с внешним габаритом 3х3.

import java.util.Arrays;
import java.util.Scanner;

public class Solution {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int[][] arr = new int[6][6];
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                arr[i][j] = in.nextInt();
            }
        }
        System.out.println(solve(arr));
    }

    private static int solve(int[][] arr) {
        int[] sum = new int[16];
        int h = 0;

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                sum[h] = arr[i][j] + arr[i][j + 1] + arr[i][j + 2]
                    + arr[i + 1][j + 1]
                    + arr[i + 2][j] + arr[i + 2][j + 1] + arr[i + 2][j + 2];
                h++;
            }
        }

        Arrays.sort(sum);
        return sum[sum.length - 1];
    }

}

Perl-решение

Здесь уже можно задать в скрипте габариты паттерна «часов» и подать на вход матрицу произвольного размера (конечно, с учётом того, что паттерн должен в ней помещаться).

#!/usr/bin/env perl
require 5.008_008;
use warnings;
use strict;
use utf8;

# hourglass dimensions, min 3x3
my $hg_dim = {
    'x' => 3, # width, must be odd
    'y' => 3, # height
};

$hg_dim->{wdht} = $hg_dim->{x} - 1; #i
$hg_dim->{hght} = $hg_dim->{y} - 1; #j
$hg_dim->{cntr} = sprintf("%u", $hg_dim->{x} / 2);

my $arr = [];
while (<STDIN>) {
    chomp;
    push @{$arr}, [ split(' ', $_) ];
}

# ...or $#{$arr-$hg_dim-1>[0]}+1 - $hg_dim-1
my $max_x = (scalar @{$arr->[0]}) - ($hg_dim->{wdht});
my $max_y = (scalar @{$arr}) - ($hg_dim->{hght});

# for neg nums, or add $sum on array and sort it
my $max_sum = -1000;

for (my $y = 0; $y < $max_y; $y++) {
    for (my $x = 0; $x < $max_x; $x++) {
        my $sum = 0;
        for (my $i = $x; $i <= $x + $hg_dim->{wdht}; $i++) {
            $sum += $arr->[$y]->[$i];                   # upper row
            $sum += $arr->[$y + $hg_dim->{hght}]->[$i]; # lowest row
        }
        for (my $j = $y + 1; $j < $y + $hg_dim->{hght}; $j++) {
            $sum += $arr->[$j]->[$x + $hg_dim->{cntr}]; # column
        }
        $max_sum = ($sum > $max_sum) ? $sum : $max_sum;
    }
}

print $max_sum, $/;

Что в итоге?

В итоге — оба приведённых решения работают, причём — по сию пору. Это отрадно 🙂 По традиции — они же выложены на GitHub.

https://www.hackerrank.com/challenges/30-2d-arrays/problem