#!/usr/bin/perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Indent = 1; $Data::Dumper::Sortkeys = 1; sub read_input { open(my $io, '<', 'input.txt') or die $!; return <$io>; } my @lines = read_input(); my %config; my $hashref = \%config; # stack of hash references my @ref; # count of | characters in a respective line my $level = 0; # count of | characters in the previous line my $prev_level = 0; my $key; my $fkey; for (@lines) { chomp; my @f = split(/\|/); $level = @f - 1; if ($level == 0) { my @f = split(/=/); $hashref->{ $f[0] } = $f[1]; } else { my @q = split(/:/, $f[$level - 1]); if ($key && $level <= $prev_level) { if (/\Q$key\E/) { my @f = split(/=/, $f[$level]); $hashref->{ $f[0] } = $f[1]; $prev_level = $level; } elsif (/\Q$fkey\E/) { $hashref = $ref[-1]; $hashref->{$q[1]} = {}; $hashref = $hashref->{$q[1]}; $key = join(':', @q); $prev_level = $level; redo; } else { pop @ref; if ($level < $prev_level) { my $diff = $prev_level - $level; while ($diff--) { pop @ref; pop @ref; } } $hashref = pop @ref; $key = ''; $prev_level = $level; redo; } } else { if (exists $hashref->{$q[0]}) { push @ref, $hashref; $hashref->{$q[0]}->{$q[1]} = {}; $hashref = $hashref->{$q[0]}->{$q[1]}; } else { push @ref, $hashref; $hashref->{$q[0]} = {}; $hashref = $hashref->{$q[0]}; push @ref, $hashref; $hashref->{$q[1]} = {}; $hashref = $hashref->{$q[1]}; } $key = join(':', @q); $fkey = $q[0]; $prev_level = $level; redo; } } } print Dumper( \%config );