Arrays starting at 1 and being closed intervals is mostly just worse than starting at 0 and being half-open intervals.
Here's an expression to take an integer b and "mod it" into an interval from a to c, given the normal convention from C++ or Python or whatever where intervals are [a, c):
(b-a)%(c-a)+a
And here it is in the lua convention where intervals are [a,c]:
(b-a)%(c-a+1)+a
This is a generalization of what you'd do if you got a really big random integer and you wanted to use it to pick from an array. For that, normally you'd write
Yes there are many algorithms that are naturally 0 indexed. But there are also many that are naturally 1 indexed! This is somewhat unscientific, but I once went through the first quarter of an algorithms textbook. And counted how many were naturally one based or zero based. And on most it didn't matter, but there were slightly more one based ones.
Can you give us some examples of one-based algorithms?
I've done a lot of programming in one-based languages, and now avoid such languages as much as possible (sometimes have no choice) because nothing seems to naturally fit into that.
This is unlikely something you'll use in practice, but I just read about it so it came to mind.
A Braun tree is a binary tree that represents a flexible array (indexable everywhere and extendable at both ends). The gist of it is that you take your array index and read it as a binary string that tells you how to go down the tree. If your index is 1, then you're at the right place and you stop. Then you go left/right depending on whether the remainder is 0/1. That is the 1-based interpretation, and it works because 1 is in the first digit while 2 and 3 need the next digit as well.
If you want to use 0-based indices, it doesn't work out as cleanly, because 0 and 1 share the same digit, while 1 and 2 use different digits. So now you have to branch on whether your index is odd or even, and then either (i-1)/2, or (i/2)-1.
It's not a big deal either way, but it turns a simple to visualize data structure into one where you have to think about the indices.
Binary heaps are more commonly known and nicer to work with in 1-based arrays for the same reason. If arrays are 1-based, a binary heap's node's children are at 2n and 2n+1, and the node's parent is at n/2.
You shouldn't need a branch in a 0-based Braun tree though. (n-1)/2 should be correct all the time.
any kind of numerical method (RKs, FDs, CN) where the n-th step a_n = f(a_(n-1)) and hence you define NUM_STEPS and the the result is a[NUM_STEPS] where a is your numerical lattice.
you could work in a 0-based index and your n-th step is a_(n-1) and so the final step is a[NUM_STEPS - 1]
in numerical analysis I don't believe i've ever cared that much about slicing. if i wanted to look at a single element in a matrix a_(ij), then I call the matrix a[i,j]. if you had to implement a pivoting algorithm then it's quite useful to call the pivot element a[i,j] and pivot row a[i,:]. i believe most devs would prefer not to have to call elements everytime a[i-1,j-1].
guessing most math guys have worked with both 0 and 1 systems and honestly don't care that much.
For an iterative method, you have an initial value a[0], then take your NUM_STEPS steps, so the final result is a[NUM_STEPS]. If it's one-based, the final result is a[NUM_STEPS+1]. This type of thing trips up my Matlab (one-based) students all the time.
In zero-based linear algebra, the indices i and j start at 0, so the top left entry of a matrix is a[0, 0], the pivot element is a[i, j] and the pivot row is a[i, :]. There isn't any adjustment needed.
Finite differences, Simpson's Rule, etc., seem more natural with zero-based too. x_0 is the left-most value, x_n is the right-most value, and the interval is divided into n pieces.
As Jef Raskin famously observed: "intuitive" just means "familiar". O- vs 1- based indexing is a source of curious passion for many people, as it really just reflects what you first learned and (consequently) what mental model you are using. Like most matters of taste, there is no objectively correct answer.
If you came up in assembly language and C, like me, you tend to think of array indices as offsets, and the first item obviously has an offset of 0. Anything else is absurd. If you came up in any number of environments that view collections like arrays from the standpoint of something like set theory, then the first (1st!) item clearly has an index of 1. What would a zeroeth item even mean?!. See---it's just point of view and familiarity.
I resisted Python for years because I just couldn't get past the clearly fragility and cognitive burden of something so mind-bogglingly stupid as meaningful whitespace. It took me a while to realize this was much more about me than about Python.
You bounce off of these contextual things all the time in Mathematics: Is 1 prime? Do the Whole numbers include 0? Etc., etc. The answer is---depends on who you ask and what you're working on. It can be implicit, especially to a community (like, say, users of a programming language), or it may need to be explicit to avoid confusion "In this house, we obey the Fundamental Theorem of Arithmetic! 1 is not prime!" As long as you get those particular ducks in a row, the problem is mostly just impedance from people mistaking their personal experience for natural law.