<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.antonfagerberg.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.antonfagerberg.com/" rel="alternate" type="text/html" /><updated>2026-04-17T08:03:51+00:00</updated><id>https://www.antonfagerberg.com/feed.xml</id><title type="html">Anton Fagerberg</title><subtitle>The personal website of Anton Fagerberg, it&apos;s about programming, reading books and other things I find interesting.</subtitle><entry><title type="html">Apple Mail: lost mails, broken backups</title><link href="https://www.antonfagerberg.com/apple-mail-lost-mails-broken-backups/" rel="alternate" type="text/html" title="Apple Mail: lost mails, broken backups" /><published>2025-09-19T00:00:00+00:00</published><updated>2025-09-19T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/apple-mail-lost-mails-broken-backups</id><content type="html" xml:base="https://www.antonfagerberg.com/apple-mail-lost-mails-broken-backups/"><![CDATA[<p>This is a story about how mails suddenly disappeared from Apple Mail (hosted on iCloud), how I got them back and how I found out that the export (backup) is completely broken in Apple Mail on macOS.</p>

<p>As for my setup, I host my e-mail on iCloud using the iCloud+ feature where I can use my own domain name (so I have the flexibility to move along when things stops working). I’ve had this domain for years and have about 20 years worth of e-mails. I use the official Apple Mail-clients, both on my various Macs and on my iPhone (and Apple Watch I guess).</p>

<h2 id="things-are-missing">Things are missing</h2>

<p>In September of 2025 I noticed that I was missing an important mail. I couldn’t figure out what happened but I had a suspicion it might be Apple’s fault (maybe because I read <a href="https://tenderlovemaking.com/2025/09/17/apple-photos-app-corrupts-images/">Apple Photos App Corrupts Images</a> the night before with a lot of comments on Hacker News about sync being broken in weird ways) - I have not had this issue myself though. To my advantage, I had a MacBook Pro that was offline and I hoped the mail would still be there - also luckily, the computer was completely out of battery so no “app nap” syncing mail while being suspended.</p>

<p>I blocked the internet access for that Mac, booted it up and found the mail I was looking for! But I also found a lot of other mails compared to my iPhone and my other Mac that was synced. When looking at the count, I saw that a whopping 5,396 mails were missing. About 1/4th of all my emails were gone!</p>

<p>Luckily, I do have backups. Unfortunately, it was a while since I did my last backup. I proceeded to take a fresh backup (export) on my synced machine, one on the the offline machine, downloaded my latest backup and started comparing them.</p>

<p>My method of comparison was fairly simple, essentially I did <code class="language-plaintext highlighter-rouge">grep "^From " mbox</code>, normalized to lowercase, sorted the lines and did a diff. The result showed that everything was a big mess. All backups had partial information but there were hundreds of mails only present in either one of the three backup. No single backup could show a complete picture.</p>

<p>Maybe things had gotten a little corrupted over time and had recently gone completely haywire. I don’t know why it happened now but my suspicion was that upgrading to iOS 26 may have triggered this since that release seems very buggy. I’ve also upgraded my work machine to MacOS 26 (Tahoe) but I don’t use my private mail on that machine, although it is connected to iCloud and some general mail settings like Smart Mailboxes seem to sync in the client. My other Macs are running older versions (Sonoma and Sequioa) and can’t be upgraded to Tahoe.</p>

<h2 id="apple-support">Apple support</h2>

<p>My initial knee-jerk reaction would be to write an angry blog, ditch Apple Mail / iCloud and move somewhere else. But I thought, I’m gonna give Apple the benefit of doubt. I’ve never contacted Apple support before - but I’ve had very bad experiences with other big tech companies’ support.</p>

<p>I started with online chat, it started as it usually do: “Hi! My name is Shahbaz. I hope you are doing good.”. No, not really, Shahbaz. But, he was helpful and the interaction was quick. He created a case id and escalated to senior advisors - but told me I’d have to call them, they can’t help over chat. Ugh.</p>

<p>I called the Swedish number for Apple support, a young woman answered and remotely looked at my phone, mainly looking at settings, iCloud space usage and that I wasn’t using any filters etc. I was not confident this would lead anywhere and she couldn’t see any issues but after a while she said she would rebuild my mailbox - but I had to disable “advanced data protection” first which I did not like at all, but understandable I guess? I’m not really sure why it’s needed though because <a href="https://support.apple.com/guide/security/advanced-data-protection-for-icloud-sec973254c5f/web">according to documentation</a>:</p>

<blockquote>
  <p>Because of the need to interoperate with the global email, contacts, and calendar systems, iCloud Mail, Contacts, and Calendar aren’t end-to-end encrypted.</p>
</blockquote>

<p>Pretty much as soon as she started the process I could see the mails starting to re-appear and thousands of them started downloading. I found the important mail I was missing!</p>

<h2 id="broken-export--backups">Broken export / backups</h2>

<p>When the rebuilding / syncing was done I started a new export - now hoping to have a fresh, complete and uncorrupted backup (I followed the <a href="https://support.apple.com/guide/mail/import-or-export-mailboxes-mlhlp1030/mac">Export mailboxes</a> as described by Apple’s official documentation). When you do it you’ll get a folder called something like <code class="language-plaintext highlighter-rouge">MailboxName.partial.mbox</code> Then you wait for an eternity until the <code class="language-plaintext highlighter-rouge">.partial</code> is removed, you can watch the mbox file inside it grow in size but there is absolutely no feedback in Apple Mail that it’s doing any work, no progress bar, nothing. No indication if anything stops or hangs.</p>

<p>After the export was done, I started diffing again but everything looked completely broken again and made no sense.</p>

<p>I found out that the <code class="language-plaintext highlighter-rouge">mbox</code> format has a limit of ~2.15 GB due to use of 32-bit integers. So I needed a way to split it into smaller pieces. What I did to solve this was to use “Smart Mailboxes” and split my mails into time ranges like “received before 2010”, “between 2010-2020” etc (here I could go on a tangent about what timezone the received seems to use because that is also wild, but I digress…). I then hit export again on the smart mailbox. Nothing seemed to happen. Turns out, when you do this on a smart mailbox it looks like nothing happens. No <code class="language-plaintext highlighter-rouge">.partial</code>-folder is created. Absolutely zero feedback.</p>

<p>After “an eternity” a folder appeared called <code class="language-plaintext highlighter-rouge"> 2.mbox</code>. Yes, really, first a “blankspace”, then the number 2 (or sometimes 3 if you do another, but never 1 because god knows why…), then <code class="language-plaintext highlighter-rouge">.mbox</code>. This seems to be the way it works. I could finally get a total size larger than 2.15 so I joined all my partial exports, normalized and diffed. The count of mails in the backup at this point was larger(!?) compared to what it said in Apple Mail, so surely I should have a complete backup now. Maybe Apple Mail was just grouping things or something?</p>

<p>But it still didn’t match up. Everything still looked corrupted. I could track down specific mails that existed in older backups, but not in my new one - and the mail did exist in the Apple Mail client. It just wasn’t exported for some reason.</p>

<p>So I tried to do an export on my offline Mac (that was not synced) using the same “Smart mailbox” method. It worked fine (seemingly), no errors, but the files created were tiny in comparison to my online Mac. No way it could contain all my emails. It made no sense. At this point I just surrendered to the fact that the export functionality in Apple Mail on macOS is completely broken and there’s no way I could ever make it work reliably or trust it in any way. Things fail in different ways and you get no feedback whatsoever.</p>

<p>You should absolutely not use “export mailbox” in Apple Mail.</p>

<h2 id="thunderbird">Thunderbird</h2>

<p>So I thought, let’s try Thunderbird if it works better. So I downloaded it, entered my email account for “auto configuration” and Thunderbird crashed. I restarted it and it opened a prompt do donate money to them. I tried again and Thunderbird crashed again.</p>

<p>I moved on to manual setup, entered all the server settings, ports, ssl - then I created an app-specific password and as I added the password to Thunderbird, it cleared all server setting fields that I had painstakingly filled in. So I had to fill them in again, sigh…</p>

<p>But then it worked. However, I couldn’t see many of my mailboxes. Found out that you have to “subscribe” to them in Thunderbird. Did that and mails started downloading. Problem now was that the mail count was much larger compared to Apple mail, several thousands more. Looking around, I could see that there were a lot of duplicates in Thunderbird. So It thought “that’s great, Thunderbird is duplicating emails now”, searched around and it seemed like a common issue and at this point I started losing my mind. It was late and I was tired.</p>

<p>After pulling myself together and Thunderbird was done downloading, I tried to do an export but seems like Thunderbird has the same size limitation, but at least they are up front about it!</p>

<p><img src="/images/apple_mail/thunderbird_export.png" alt="Thunderbird export" /></p>

<p>What can be done here is that you can actually copy the mailbox files manually from the Thunderbird folder by clicking “Open profile folder” as seen in the screenshot above. I did not dig much into it but it’s probably something mbox-like, but I can see files larger than 2.15 GB so hopefully complete - but you know by this point, you need to make sure yourself.</p>

<p>However, I didn’t like the duplication issue.</p>

<h2 id="offlineimap">offlineimap</h2>
<p>Moving on, I started looking at cli solutions. I picked <a href="https://www.offlineimap.org">offlineimap</a>, set it up and started running it. At this point I noticed that offlineimap and Thunderbird actually agreed on the mail count, so maybe there was actually duplicates but Apple Mail was hiding them.</p>

<p>I enabled the iCloud web ui, logged in to my mail via the browser and it actually also agreed with Thunderbird and offlineimap about the mail count! Turns out Apple Mail on macOS is actually hiding duplicates and excluding them from the total mail count (but they are included in the broken exports).</p>

<p><img src="/images/apple_mail/agree_disagree.png" alt="Agree or disagree" />
<em>Apple Mail (Web), Thunderbird, Thunderbird backup files, offlineimap all agrees on the count. Apple Mail on Mac does not.</em></p>

<p>Finally, now I know the correct mail count, and I can use offlineimap or Thunderbird to download all of them, and I can verify the expected count in the backup and make a diff that actually works.</p>

<h2 id="unread-count">Unread count</h2>
<p>While the total count was under control, the unread count was off - and I did the mistake of trying to understand it. (Look at the screenshot above and it wil say 42 unread in Apple Mail on the web and 29 unread in the Apple Mail on macOS.)</p>

<p>With Apple Mail on Mac the unread count is inconsistent when it comes to duplicates. It will say you have 29 unread mails but you will only see 27 unread when you filter or count them manually. Turns out that if you read one of the duplicates (on another client, so one duplicate is read, one is unread) Apple Mail on Mac will mark it as read but count it as unread.</p>

<p><img src="/images/apple_mail/29_unread.png" alt="29 unread" />
<img src="/images/apple_mail/27_unread.png" alt="27 unread" /></p>

<p>With Apple Mail on the web, it will count every duplicate as individual mails so the count is “correct”(?), but you have to expand the mails to see the duplicate if you do count them manually. (Expanding duplicates 
is not possible on Apple Mail on macOS, everything regarding duplicates is hidden.)</p>

<p><img src="/images/apple_mail/inconsistent.png" alt="Inconsistent mails" />
<em>Two duplicates merged into one mail, one duplicate is read, the other is not. The combined result seem to be “not read” - but Apple Mail on different platforms do not agree on this.</em></p>

<p>On Apple Mail on iOS it does the same even though you can’t see the duplicates which is super confusing. So it will say that you have “45 unread” (total duplicate count) but when you count them in the list you will only find 30 mails because the duplicates are hidden. At one point the Apple Mail on iOS said I had 60 unread (2x the number of de-duplicated mails) and the morning after it was back to 45 (the number of duplicated unread mails).</p>

<p>I will not try to make more sense of it. Just know that mail count and unread count is highly inconsistent between Apple Mail on Mac, iOS and the web.</p>

<h2 id="conclusion">Conclusion</h2>
<p>Do not, under any circumstances, use the “Export Mailbox” functionality in Apple Mail on a Mac. It is 100% broken.</p>

<p>If you’re missing e-mails on iCloud, Apple support is actually good and can help rebuild the inbox.</p>

<p><code class="language-plaintext highlighter-rouge">mbox</code>-files has a limit of ~2.15 gb due to 32-bit integers. (Not sure why they are used anymore as every company on earth wants to subscribe me to their mailing list and flood my inbox with GBs of newsletters.)</p>

<p>CLI-tools are great, a common pattern seems to be that they work much better compared to trillion dollar companies’ software. I haven’t explored the different imap backup tools much but <a href="https://www.offlineimap.org">offlineimap</a> seems to work fine and I’ll add it to my backup server with some rsync for redundancy. Thunderbird seems fine as well if you do a manual copy and not an export.</p>

<p>Take backups regularly. Verify that they actually work.</p>

<h3 id="update-2025-10-10">Update: 2025-10-10</h3>
<p>I don’t know how the duplicates are created but it seems to be an increasing problem. Since the original writing of this post (less than a month ago), I’ve received about 100 new e-mails but I’ve also gotten 5,500 duplicates of old existing emails. No loss of e-mails though so I guess that’s something…</p>]]></content><author><name></name></author><category term="writing" /><summary type="html"><![CDATA[This is a story about how mails suddenly disappeared from Apple Mail (hosted on iCloud), how I got them back and how I found out that the export (backup) is completely broken in Apple Mail on macOS.]]></summary></entry><entry><title type="html">Advent of Code</title><link href="https://www.antonfagerberg.com/projects/advent-of-code/" rel="alternate" type="text/html" title="Advent of Code" /><published>2024-01-13T00:00:00+00:00</published><updated>2024-01-13T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/advent-of-code</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/advent-of-code/"><![CDATA[<p>At the time of writing this, I’ve been doing <a href="https://adventofcode.com">Advent of Code</a> for 9 years. 
Or put another way, I’ve been doing Advent of Code every year since it started in 2015.
Although, this may have been my last year. (I’ve been saying that for many years but I’ll try to keep away.)</p>

<h3 id="2015---first-year-in-elixir">2015 - first year in Elixir</h3>
<p>I was working at a consultancy firm and heard about this new thing called Advent of Code.
Having recently worked a lot with Elixir I decided that I was going to try to do it in that language.</p>

<p>I don’t remember much but I do remember that I finished all problems (in the end, probably not in December). 
I also remember talking to an older colleague that it had ruined his Christmas since he couldn’t “let go” of the problems when he should’ve spent time with his family (I was able to relate to this later in life).</p>

<p>It was other times back then, I ended up on ranking 410 with a solution that took over an hour - and even ranked 803 with a solution that took over 24 hours. That just doesn’t happen anymore.</p>

<h3 id="2016---second-year-in-haskell">2016 - second year in Haskell</h3>
<p>This year I decided to challenge myself by establishing a new tradition: using a new programming language every year - I don’t know why, probably just to challenge myself.</p>

<p>Being completely sold on functional programming, I decided to use Haskell.
I had done some Haskell at University but it didn’t click for me then.
Somehow I managed to solve all problems again (was it easier back then?).
I remember using <a href="https://hoogle.haskell.org">Hoogle</a> a lot which was amazing.
I also remember using something that lets you print things without having to deal with side effects, as I remember it was named pry but I can’t find it now.
Probably something inside <code class="language-plaintext highlighter-rouge">Debug.Trace</code>.</p>

<h3 id="2017---third-year-in-scala">2017 - third year in Scala</h3>
<p>In 2017 my first child was born. 
She was just two weeks old when Advent of Code started so I decided to play it safe and use a language I knew really well: Scala.
I managed to snatch 37 stars. Probably 37 more than I should’ve because I was <em>very</em> sleep deprived during this time.</p>

<h3 id="2018---fourth-year-in-java">2018 - fourth year in Java</h3>
<p>This year I had little interest in Advent of Code, I was probably a bit worn out from “life”. But this year I was moving and had just signed up for a new job in which I was going to use Java.
I hadn’t used Java for a few years and was not up to date with the new things (which at the moment was things like the <code class="language-plaintext highlighter-rouge">streams</code> API).
So I used Advent of Code as a way to practice and it was actually pretty great - but I do remember hating Java at first having worked with Scala for a very long time, I thought I’d made the worst mistake by taking this job.
In the end, I collected 8 stars. (This year a lot more people started competing, my raking was over seventy-six thousand the first day.)</p>

<p>And if you’re curious, at the time of writing I’m still on the same job, I write a lot of Java and I really enjoy it!</p>

<h3 id="2019---firth-year-in-kotlin">2019 - firth year in Kotlin</h3>
<p>I started feeling the Kotlin hype and I felt like Kotlin would be an easy language to learn given that I already knew Java and Scala.
The problems was a bit weird this year, as I remember it, but very fun. 
I especially remember that you had to write something like a virtual machine and build a playable game inside it.
Many puzzles built on top of the solutions for the previous puzzles which was a bit tedious.
Got 28 stars that year. Didn’t get hooked on Kotlin.</p>

<h3 id="2020---sixth-year-in-clojure">2020 - sixth year in Clojure</h3>
<p>This year my second child was born so I had practically no spare time and no sleep (again).
I decided to use Clojure nonetheless as I’d wanted to try a Lisp for a very long time.
In the end, I only solved two days (four stars) in Clojure, collected a total of 7 stars in the end using other languages.
Good decision to throw in the towel.</p>

<h3 id="2021---seventh-year-in-ruby">2021 - seventh year in Ruby</h3>
<p>My girlfriend was “very pregnant” at this time. Our second son (third child) was expected the next month so I had to take care of our two other children on my own a lot at this point in time. I decided to pick a language I was vaguely familiar with but which would still let me get away with “a new language every year” - so I picked Ruby.
I’m not sure why but I hated using Ruby this year (I liked it before, also, turns out I didn’t remember much of it). I felt like it was a stupid idea to use a new language “just because” - but I completed 8 stars in Ruby and then did some more in Java. The end result was 30 stars.</p>

<h3 id="2022---eighth-year-in-go">2022 - eighth year in Go</h3>
<p>If you’ve been reading along, at this point in time I had three small kids - one of them not one year old yet.
This year I went back and picked a truly new language for me: Go.
I enjoyed this year a lot and actually learned quite a lot of Go.
It’s a language I would consider using more.
18 stars was collected that year which felt like enough.</p>

<h3 id="2023---ninth-year-competition--back-to-java">2023 - ninth year (competition / back to Java)</h3>
<p>At first, I planned to use OCaml to keep the “new language every year” tradition alive. I started learning it a bit in advance and I thought I was going to love it when reading the documentation.
But when I started using it I really didn’t like it. It was clunky to write things (like printing a nested map to stdout) and the build tool Dune was finicky for some reason.
(Most of these things are probably my fault, but you know…).
My plan was to solve one problem and then throw in the towel.</p>

<p>Instead, what happened was that my job announced this internal competition. 
I <em>hate</em> competing but I thought, you know what, I’m going to go all in on that this year - for once in my life.
End it with a bang.
I’ve been doing this for so long, and if I’m gonna compete in something it’s going to be this.
So I picked Java as my language (breaking tradition) to ensure that I had something I was very comfortable using.</p>

<p>In the end I collected 47 stars. I even got in the top 1000 for one problem (hey, place 999 counts!).
I didn’t try to compete globally as that is way out of my league, and wasn’t trying to be particularly fast - just a bit faster than everyone in my company.</p>

<p>I learned a lot of new things about algorithms this year and a few new details about Java (like the iterator of a <code class="language-plaintext highlighter-rouge">PriorityQueue</code> will not return items in the sorted order… ugh…).</p>

<h3 id="links-to-the-pages-i-wrote-every-year">Links to the pages I wrote every year</h3>

<ul>
  <li>
    <p><a href="/projects/advent-of-code-2023/">Advent of Code 2023</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-2022/">Advent of Code 2022 in Go</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-2021/">Advent of Code 2021 in Ruby</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-2020/">Advent of Code 2020 in Clojure</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-2019/">Advent of Code 2019 in Kotlin</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-2018/">Advent of Code 2018 in Java</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-2017/">Advent of Code 2017 in Scala</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-2016/">Advent of Code 2016 in Haskell</a></p>
  </li>
  <li>
    <p><a href="/projects/advent-of-code-in-elixir/">Advent of Code 2015 in Elixir</a></p>
  </li>
</ul>]]></content><author><name></name></author><category term="projects" /><category term="code" /><summary type="html"><![CDATA[At the time of writing this, I’ve been doing Advent of Code for 9 years. Or put another way, I’ve been doing Advent of Code every year since it started in 2015. Although, this may have been my last year. (I’ve been saying that for many years but I’ll try to keep away.)]]></summary></entry><entry><title type="html">Advent of Code 2023</title><link href="https://www.antonfagerberg.com/projects/advent-of-code-2023/" rel="alternate" type="text/html" title="Advent of Code 2023" /><published>2023-12-06T00:00:00+00:00</published><updated>2023-12-06T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/advent-of-code-2023</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/advent-of-code-2023/"><![CDATA[<p>This year I had planned on using <a href="https://ocaml.org">OCaml</a>. It looked really nice when reading the docs and I used it for some old problems, but it was just a bit too tedious to do certain things (just printing a list of strings nested in another list required some work - unless I added a third-party “deriving” tool). That and the workflow of building / running / debugging was just too much for me this year.</p>

<p>Instead, I decided to join the friendly competition at work (private leaderboard), so I’ll try to do as many as I have time for using Java instead. Focus will be on refreshing my knowledge on algorithms instead of learning a new language.</p>

<p><a href="https://github.com/AntonFagerberg/advent_of_code_2023">Advent of Code 2023 on GitHub</a></p>

<h3 id="previous-years">Previous years</h3>
<ul>
  <li><a href="/projects/advent-of-code-in-elixir/">2015 in Elixir</a></li>
  <li><a href="/projects/advent-of-code-2016/">2016 in Haskell</a></li>
  <li><a href="/projects/advent-of-code-2017/">2017 in Scala</a></li>
  <li><a href="/projects/advent-of-code-2018/">2018 in Java</a></li>
  <li><a href="/projects/advent-of-code-2019/">2019 in Kotlin</a></li>
  <li><a href="/projects/advent-of-code-2020/">2020 in Clojure</a></li>
  <li><a href="/projects/advent-of-code-2021/">2021 in Ruby (and some Java)</a></li>
  <li><a href="/projects/advent-of-code-2022/">2022 in Go</a></li>
</ul>]]></content><author><name></name></author><category term="projects" /><category term="advent-of-code" /><summary type="html"><![CDATA[This year I had planned on using OCaml. It looked really nice when reading the docs and I used it for some old problems, but it was just a bit too tedious to do certain things (just printing a list of strings nested in another list required some work - unless I added a third-party “deriving” tool). That and the workflow of building / running / debugging was just too much for me this year.]]></summary></entry><entry><title type="html">Snake games</title><link href="https://www.antonfagerberg.com/projects/snake-games/" rel="alternate" type="text/html" title="Snake games" /><published>2023-11-03T00:00:00+00:00</published><updated>2023-11-03T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/snake-games</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/snake-games/"><![CDATA[<p>During a week I experimented with Java and LibGDX by making three Snake-game experiments.
They are all “one evening” projects. Very unpolished and a bit weird.</p>

<ul>
  <li><a href="/projects/snakexpand">Snakexpand</a> - you fill up the screen and it expands</li>
  <li><a href="/projects/rainbowsnake">RainbowSnake</a> - you grow a lot and eat yourself</li>
  <li><a href="/projects/snake3d">Snake3D</a> - snake in three dimensions</li>
</ul>]]></content><author><name></name></author><category term="projects" /><category term="games" /><summary type="html"><![CDATA[During a week I experimented with Java and LibGDX by making three Snake-game experiments. They are all “one evening” projects. Very unpolished and a bit weird.]]></summary></entry><entry><title type="html">Snake3D</title><link href="https://www.antonfagerberg.com/projects/snake3d/" rel="alternate" type="text/html" title="Snake3D" /><published>2023-11-02T00:00:00+00:00</published><updated>2023-11-02T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/snake3d</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/snake3d/"><![CDATA[<p>I was discussing Super Mario 3D vs 2D games with a friend who made the joke that I should make Snake in 3D (since I made <a href="/projects/snakexpand/">Snakespand</a> and <a href="/projects/rainbowsnake/">RainbowSnake</a> recently).</p>

<p>So of course I had to do that. It’s a super simple proof of concept lacking many of the proper game mechanics. I think it could be a fun project with proper camera support and other things, but I don’t think I’ll continue working on it. But you know what? It’s super fun to make these micro-projects in an hour or two. This was my first attempt at doing 3D in LibGDX.</p>

<p>(I haven’t built it for the web either like my other games so you have to compile it from source to try it… sorry!)</p>

<p><a href="https://github.com/AntonFagerberg/Snake3D">Project on GitHub</a></p>

<p><img src="https://github.com/AntonFagerberg/Snake3D/raw/main/snake3d%20cut.gif" alt="snake3d" /></p>]]></content><author><name></name></author><category term="projects" /><summary type="html"><![CDATA[I was discussing Super Mario 3D vs 2D games with a friend who made the joke that I should make Snake in 3D (since I made Snakespand and RainbowSnake recently).]]></summary></entry><entry><title type="html">RainbowSnake</title><link href="https://www.antonfagerberg.com/projects/rainbowsnake/" rel="alternate" type="text/html" title="RainbowSnake" /><published>2023-10-31T00:00:00+00:00</published><updated>2023-10-31T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/rainbowsnake</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/rainbowsnake/"><![CDATA[<p>I created an experimental game called <a href="/projects/snakexpand/">Snakespand</a> about a week ago.</p>

<p>This is a fork of it to try out some new ideas: You grow by 10 blocks every time you eat a dot, and instead of dying if you run into yourself, you’ll lose your tail from that point.</p>

<p><a href="http://www.antonfagerberg.com/RainbowSnake/">Try it out online! 🕹🐍</a></p>

<p><a href="https://github.com/AntonFagerberg/RainbowSnake">Project on GitHub</a></p>

<p><img src="https://github.com/AntonFagerberg/RainbowSnake/raw/main/RainbowSnake.gif" alt="rainbowsnake" /></p>]]></content><author><name></name></author><category term="projects" /><summary type="html"><![CDATA[I created an experimental game called Snakespand about a week ago.]]></summary></entry><entry><title type="html">Snakexpand</title><link href="https://www.antonfagerberg.com/projects/snakexpand/" rel="alternate" type="text/html" title="Snakexpand" /><published>2023-10-22T00:00:00+00:00</published><updated>2023-10-22T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/snakexpand</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/snakexpand/"><![CDATA[<p>I got this idea, what about if you make the game Snake, but you start with a really small level and if you fill it up the screen will expand.</p>

<p>At first, you’re on a 4x4 grid where you (the snake) fill up 1/4th of the world and the dot (apple?) fills up 1/4th of the screen.
When you’re 4 blocks long, and you fill up the entire screen, the world will expand.</p>

<p>Was it a good idea in theory? YES! In practice? It’s not without problems. One of them being that I had to “unroll” the snake since there’s a good chance you’re about to eat yourself after reaching the last dot.</p>

<p>It was a fun weekend project, a few hours well spent.</p>

<p>I tried using a GameBoy-inspired color scheme. No images or sprites, only drawn boxes. No sound. No Music.</p>

<p>The game was created using Java (JDK 7 which felt old), and libGDX. I compiled a version for the web so it can be played online below.</p>

<p><a href="http://www.antonfagerberg.com/snakexpand/">Try it out online! 🕹🐍</a></p>

<p><a href="https://github.com/AntonFagerberg/snakexpand">Project on GitHub</a></p>

<p><a href="https://github.com/AntonFagerberg/snakexpand/blob/main/core/src/com/antonfagerberg/snaketon/SnakeTon.java">Actual code</a></p>

<p><img src="https://github.com/AntonFagerberg/snakexpand/raw/main/snakexpand.gif" alt="snakexpand" /></p>]]></content><author><name></name></author><category term="projects" /><summary type="html"><![CDATA[I got this idea, what about if you make the game Snake, but you start with a really small level and if you fill it up the screen will expand.]]></summary></entry><entry><title type="html">Item limited cache</title><link href="https://www.antonfagerberg.com/projects/item-limited-cache/" rel="alternate" type="text/html" title="Item limited cache" /><published>2023-10-20T00:00:00+00:00</published><updated>2023-10-20T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/item-limited-cache</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/item-limited-cache/"><![CDATA[<p>I’ve been meaning to start doing a couple of “micro-projects” just for fun.
First up got to be this item limited cache. It’s a simple cache that will keep at most X items. Every time an item is accessed a counter for that item goes up. If the cache is full when a new items is added, one of the items with the lowest access count is discarded (if many items has the same access score, it will be the first one defined by the iterator of the underlying Set).</p>

<p>It is implemented using a HashMap for fast access of the items, and a TreeMap for accessing the least used items.</p>

<h3 id="example">Example</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// New cache that can hold 3 items</span>
<span class="nc">ItemLimitedCache</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">String</span><span class="o">&gt;</span> <span class="n">cache</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ItemLimitedCache</span><span class="o">&lt;&gt;(</span><span class="mi">3</span><span class="o">);</span>

<span class="n">cache</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"A"</span><span class="o">,</span> <span class="s">"A"</span><span class="o">);</span>
<span class="n">cache</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"B"</span><span class="o">,</span> <span class="s">"B"</span><span class="o">);</span>
<span class="n">cache</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"C"</span><span class="o">,</span> <span class="s">"C"</span><span class="o">);</span>

<span class="n">cache</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"A"</span><span class="o">);</span>
<span class="n">cache</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"A"</span><span class="o">);</span>
<span class="n">cache</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"A"</span><span class="o">);</span>
<span class="c1">// A has been accessed 3 times</span>

<span class="n">cache</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"B"</span><span class="o">);</span>
<span class="n">cache</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"B"</span><span class="o">);</span>
<span class="c1">// B has been accessed 2 times</span>

<span class="n">cache</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"C"</span><span class="o">);</span>
<span class="c1">// C has been accessed 1 time</span>

<span class="n">cache</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"D"</span><span class="o">,</span> <span class="s">"D"</span><span class="o">);</span>
<span class="c1">// C is replaced by D</span>
</code></pre></div></div>

<p><a href="https://github.com/AntonFagerberg/JavAnton/blob/main/cache/src/main/java/com/antonfagerberg/javanton/cache/ItemLimitedCache.java">Source code on GitHub</a></p>]]></content><author><name></name></author><category term="projects" /><category term="code" /><summary type="html"><![CDATA[I’ve been meaning to start doing a couple of “micro-projects” just for fun. First up got to be this item limited cache. It’s a simple cache that will keep at most X items. Every time an item is accessed a counter for that item goes up. If the cache is full when a new items is added, one of the items with the lowest access count is discarded (if many items has the same access score, it will be the first one defined by the iterator of the underlying Set).]]></summary></entry><entry><title type="html">Advent of Code 2022 in Go</title><link href="https://www.antonfagerberg.com/projects/advent-of-code-2022/" rel="alternate" type="text/html" title="Advent of Code 2022 in Go" /><published>2022-12-01T00:00:00+00:00</published><updated>2022-12-01T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/advent-of-code-2022</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/advent-of-code-2022/"><![CDATA[<p>It’s that time of the year again: <a href="http://adventofcode.com">Advent of Code</a>!
I read a good blog post that you should always focus on doing one thing at a time -
for example, not learning a new language and solve an unknown problem at the same time.
Advent of code has been a way for me to explore different programming languages every year.
Last year I gave up on Ruby after a few problems and continued with Java - just to solve more problems.</p>

<p>This year my focus will be on learning <a href="https://go.dev">Go</a>, and because of that I
will do fewer problems (and probably focus on the smaller ones) - the goal is to learn a completely new language,
not solve as many problems as possible.</p>

<p>The second (bigger) challenge for me this year will be to invest a healthy amount of time into this.
It’s sooo easy to get carried away and stay up way too late just to complete another problem.
This year I will need to handle that aspect better - I have three small kids now and I desperately need decent sleep
and down time.</p>

<p>Anyway, Go has been on my radar for a long time, it seems to be a really nice low level-ish language.
Simple but powerful. I hope it will be a good addition to my toolbox of programming languages.
I’ve been playing around with my old <a href="https://www.raspberrypi.com">Raspberry Pi 2 &amp; 3</a>
and Go seems to be a good fit for writing software for these low performance devices.</p>

<p>Without further ado, <a href="https://github.com/AntonFagerberg/advent_of_code_2022">Advent of Code 2022 in Go!</a></p>

<h3 id="previous-years">Previous years</h3>
<ul>
  <li><a href="/projects/advent-of-code-in-elixir/">2015 in Elixir</a></li>
  <li><a href="/projects/advent-of-code-2016/">2016 in Haskell</a></li>
  <li><a href="/projects/advent-of-code-2017/">2017 in Scala</a></li>
  <li><a href="/projects/advent-of-code-2018/">2018 in Java</a></li>
  <li><a href="/projects/advent-of-code-2019/">2019 in Kotlin</a></li>
  <li><a href="/projects/advent-of-code-2020/">2020 in Clojure</a></li>
  <li><a href="/projects/advent-of-code-2021/">2021 in Ruby/Java</a></li>
</ul>]]></content><author><name></name></author><category term="projects" /><category term="advent-of-code" /><summary type="html"><![CDATA[It’s that time of the year again: Advent of Code! I read a good blog post that you should always focus on doing one thing at a time - for example, not learning a new language and solve an unknown problem at the same time. Advent of code has been a way for me to explore different programming languages every year. Last year I gave up on Ruby after a few problems and continued with Java - just to solve more problems.]]></summary></entry><entry><title type="html">Advent of Code 2021 in Ruby</title><link href="https://www.antonfagerberg.com/projects/advent-of-code-2021/" rel="alternate" type="text/html" title="Advent of Code 2021 in Ruby" /><published>2021-12-02T00:00:00+00:00</published><updated>2021-12-02T00:00:00+00:00</updated><id>https://www.antonfagerberg.com/projects/advent-of-code-2021</id><content type="html" xml:base="https://www.antonfagerberg.com/projects/advent-of-code-2021/"><![CDATA[<p>Another year of <a href="http://adventofcode.com">Advent of Code</a>, no tradition like it! 🎄</p>

<p>I’ve probably got even less time than last year (it’s a bad trend right now…), but I’ll do a few just to keep the tradition alive.
This year I’ll use <a href="https://www.ruby-lang.org/en/">Ruby</a>. Don’t have a good motivation why.</p>

<p>Update: after solving a few problems in Ruby, I started getting tired of using a language I’m not that familiar with. It was a great idea the first years and I learned a lot, especially when doing pure FP in Haskell and some actor based things in Elixir, but at this point I don’t really dig deep into the languages - and to be honest, a lot of the languages I’ve chosen are very similar. Ruby and Java are considered different but they aren’t fundamentally <em>that</em> different.</p>

<p>I decided to continue doing some of the problems this year in Java instead because I enjoy the problems and I mostly use Java professionally at this point in my career so there’s no friction when using it. It’s hard to give up a streak of using new languages, but I think it’s a wise decision. When my kids are older and I have more time, I can see myself getting into a real challenge like doing them in APL or Prolog. But for now, I’ll go ahead and enjoy the puzzles with a language I already know by heart.</p>

<p><a href="https://github.com/AntonFagerberg/advent-of-code-2021">Advent of Code 2021 in Ruby (problem 1-4)</a></p>

<p><a href="https://github.com/AntonFagerberg/advent_of_code_2021">Advent of Code 2021 in Java, problem 5+</a></p>

<h3 id="previous-years">Previous years</h3>
<ul>
  <li><a href="/projects/advent-of-code-in-elixir/">2015 in Elixir</a></li>
  <li><a href="/projects/advent-of-code-2016/">2016 in Haskell</a></li>
  <li><a href="/projects/advent-of-code-2017/">2017 in Scala</a></li>
  <li><a href="/projects/advent-of-code-2018/">2018 in Java</a></li>
  <li><a href="/projects/advent-of-code-2019/">2019 in Kotlin</a></li>
  <li><a href="/projects/advent-of-code-2020/">2020 in Clojure</a></li>
</ul>]]></content><author><name></name></author><category term="projects" /><category term="advent-of-code" /><summary type="html"><![CDATA[Another year of Advent of Code, no tradition like it! 🎄]]></summary></entry></feed>