Contents of this directory is archived and no longer updated.

Summer Scripting Games 2009 И оно свершилось! Хотя официально Scripting Games начинаются только 15-го июня, но уже со вчерашнего дня стали известны уже 2 задания. Для начала немного информации, что и как:

В принципе, вы можете решать задания как угодно, т.к. засчитываются все, которые отвечают условиям задания.

Итак, Event1 и оба дивизиона:

Beginner Division

Из Competitors Pack нам потребуется файл 100 Meter Event.txt

Задача:

  • Выяснить, как читать файл?
  • Как прочитать из каждой строки поля Name, Country, Time?
  • Как отсортировать содержимое файла по полю Name?
  • Выбрать 3-х победителей из списка. Победителем считается тот, у кого самое маленькое время в колонке Time
  • Показать поля Name, Country и Time для первых 3-х победителей.

Решение:

Побегав курсором по файлу я обнаружил тот факт, что разделителем между столбцом Name и Country является табулятор ([Tab]), а между Country и Time стоит один пробел во второй строке, а в остальных строках стоит [Tab]. Следовательно, варианты использования командлетов с параметром –Delimeter не прокатят и нужно будет разбирать всё регулярными выражениями. Первый вопрос наталкивает на необходимость чтения файла не через Get-Content, а через [system.io.file]::ReadAllText(). Но я не вижу особого криминала в использовании родного для PowerShell командлета Get-Content. Это будет несложно. Основная проблема в том, как составить регулярное выражение. Я решил разобрать имя на First Name и LastName (т.к. правильней, всё же, будет, когда сначала идёт имя, а потом фамилия), далее выбрать Country от табуляции до первого числа. Причём, тут потребуется каждую часть сделать именованной (named capture). Если открыть PowerShell In Action на 111 странице, то там можно найти описание, как делать named captures. У меня регулярное выражение получилось вот такое:

^(?<ln>\w+)..(?<fn>.*)\t(?<country>.+)(?<time>\d\.\d+)

Что делает это выражение:

  • в секцию LN (LastName) попадают все буквы до первого небуквенного знака.
  • далее пропускаем 2 символа (запятую и пробел).
  • в секцию FN (FirstName) попадает всё до первой табуляции.
  • после табуляции идёт Country и в него запишем всё, вплоть до первого числового знака.
  • И числа записываем в секцию Time.

Давайте проверим его:

[↓] [vPodans] $file = gc '.\100 Meter Event.txt'
[↓] [vPodans] $file[1] -match "^(?<ln>\w+)..(?<fn>.*)\t(?<country>.+)(?<time>\d\.\d+)"
True
[↓] [vPodans] $matches

Name                           Value
----                           -----
country                        Australia
ln                             Aaberg
fn                             Jesper
time                           8.57
0                              Aaberg, Jesper    Australia 8.57


[↓] [vPodans] $file[11] -match "^(?<ln>\w+)..(?<fn>.*)\t(?<country>.+)(?<time>\d\.\d+)"
True
[↓] [vPodans] $matches

Name                           Value
----                           -----
country                        Japan
ln                             Hansen
fn                             Anne Grethe
time                           8.85
0                              Hansen, Anne Grethe    Japan    8.85


[↓] [vPodans]

и теперь соберём объект с нужными свойствами и отправим его на выход. На выходе отсортируем объекты по параметру Time и выберем первые 3 объекта:

gc "100 Meter Event.txt" | ?{$_ -match "^(?<ln>\w+)..(?<fn>.*)\t(?<country>.+)(?<time>\d\.\d+)"} |%{
    $obj = "" | Select @{n='Name';e={$matches.fn + " " + $matches.ln}},
    @{n='Country';e={$matches.country}},@{n='Time';e={$matches.time}}
    $obj
} | sort time | select -First 3 | ft -AutoSize

и вот вывод:



решил ещё отформатировать в Format-Table с ключом –AutoSize для красоты. Признаюсь, что это задание меня сильно озадачило. Для меня оно оказалось очень непростым (такие дела).

Advanced Division

Для этой задачи нам потребуется файл Personal Information Cards_ADV1.txt из Competitors Pack.

Задача:

  • найти самую короткую строку в файле, которая содержит какой-либо текст.
  • вывести на экран 3 самые короткие строчки

Решение:

В файле много пустых строк, но это не проблема. Итак, one-liner решение:

gc "Personal Information Cards_ADV1.txt" | ?{$_.trim().length -ne 0} | sort length | select -First 3
[↓] [vPodans] gc "Personal Information Cards_ADV1.txt" | ?{$_.trim().length -ne 0} | select –First 3
PPID
Claims
Street
[↓] [vPodans]

Странно, что в Advanced Division получилось такое простое задание.


Share this article:

Comments:

Comments are closed.