diff --git a/AdventOfCode.lpi b/AdventOfCode.lpi
new file mode 100644
index 0000000..4333dce
--- /dev/null
+++ b/AdventOfCode.lpi
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
diff --git a/AdventOfCode.lpr b/AdventOfCode.lpr
new file mode 100644
index 0000000..173894a
--- /dev/null
+++ b/AdventOfCode.lpr
@@ -0,0 +1,103 @@
+{
+ Solutions to the Advent Of Code.
+ Copyright (C) 2023 Stefan Müller
+
+ This program is free software: you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program. If not, see .
+}
+
+program AdventOfCode;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}
+ cthreads,
+ {$ENDIF}
+ Classes, SysUtils, CustApp, UTrebuchet;
+
+type
+
+ { TAdventOfCode }
+
+ TAdventOfCode = class(TCustomApplication)
+ private
+ procedure RunPuzzleSolutions;
+ protected
+ procedure DoRun; override;
+ public
+ constructor Create(TheOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure WriteHelp; virtual;
+ end;
+
+{ TAdventOfCode }
+
+procedure TAdventOfCode.RunPuzzleSolutions;
+begin
+ TTrebuchet.Solve;
+end;
+
+procedure TAdventOfCode.DoRun;
+var
+ ErrorMsg: String;
+begin
+ // quick check parameters
+ ErrorMsg := CheckOptions('h', 'help');
+ if ErrorMsg <> '' then
+ begin
+ ShowException(Exception.Create(ErrorMsg));
+ Terminate;
+ Exit;
+ end;
+
+ // parse parameters
+ if HasOption('h', 'help') then
+ begin
+ WriteHelp;
+ Terminate;
+ Exit;
+ end;
+
+ { add your program here }
+ RunPuzzleSolutions;
+
+ // stop program loop
+ Terminate;
+end;
+
+constructor TAdventOfCode.Create(TheOwner: TComponent);
+begin
+ inherited Create(TheOwner);
+ StopOnException := True;
+end;
+
+destructor TAdventOfCode.Destroy;
+begin
+ inherited Destroy;
+end;
+
+procedure TAdventOfCode.WriteHelp;
+begin
+ { add your help code here }
+ writeln('Usage: ', ExeName, ' -h');
+end;
+
+var
+ Application: TAdventOfCode;
+begin
+ Application := TAdventOfCode.Create(nil);
+ Application.Title := 'Advent of Code 2023';
+ Application.Run;
+ Application.Free;
+end.
+
diff --git a/puzzles/utrebuchet.pas b/puzzles/utrebuchet.pas
new file mode 100644
index 0000000..0cd514e
--- /dev/null
+++ b/puzzles/utrebuchet.pas
@@ -0,0 +1,81 @@
+unit UTrebuchet;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+type
+
+ { TTrebuchet }
+
+ TTrebuchet = class(TObject)
+ private
+ FValue: Integer;
+ procedure RunSolution;
+ procedure ProcessDataLine(const ALine: string);
+ public
+ class procedure Solve; static;
+ constructor Create;
+ end;
+
+implementation
+
+{ TTrebuchet }
+
+procedure TTrebuchet.RunSolution;
+var
+ data: TextFile;
+ s: string;
+begin
+ AssignFile(data, ConcatPaths(['data', 'trebuchet_calibration_document.txt']));
+ try
+ reset(data);
+ while (not EOF(data)) do
+ begin
+ readln(data, s);
+ ProcessDataLine(s);
+ end;
+ finally
+ CloseFile(data)
+ end;
+ WriteLn(FValue);
+end;
+
+procedure TTrebuchet.ProcessDataLine(const ALine: string);
+var
+ c: Char;
+ first, last: Integer;
+begin
+ first := -1;
+ last := -1;
+ for c in ALine do
+ begin
+ if c in ['0'..'9'] then
+ begin
+ last := StrToInt(c);
+ if first < 0 then
+ first := last;
+ end;
+ end;
+ Inc(FValue, first * 10 + last);
+end;
+
+class procedure TTrebuchet.Solve;
+var
+ trebuchet: TTrebuchet;
+begin
+ WriteLn('--- Day 1: Trebuchet?! ---');
+ trebuchet := TTrebuchet.Create;
+ trebuchet.RunSolution;
+end;
+
+constructor TTrebuchet.Create;
+begin
+ FValue := 0;
+end;
+
+end.
+