ChatGPT - Complex Coding Challenges: 8 KYU
Tags: chatgpt, javascript, c, sql
Published: 2023-03-01 17:29:53

Time for the first challenge in this series!

Well actually, the first challenge was picking a language to use for this little experiment.

As I could not decide between choosing something familiar or something I do not know, I have decided to choose 3 languages for each task!

So we have JavaScript, C and SQL and each challenge will be attempted using all 3 of these.

Talking of our first challenge, here it is: [Century From Year](https://www.codewars.com/kata/5a3fe3dde1ce0e8ed6000097)

This challenge has the following description.

```bash
Introduction
The first century spans from the year 1 up to and including the year 100, the second century - from the year 101 up to and including the year 200, etc.

Task
Given a year, return the century it is in.

Examples
1705 --> 18
1900 --> 19
1601 --> 17
2000 --> 20

Note: this kata uses strict construction as shown in the description and the examples, you can read more about it here
```
So let's put ChatGPT to work!

**Solving it in JavaScript**

```bash
Given the following code challenge:

Introduction
The first century spans from the year 1 up to and including the year 100, the second century - from the year 101 up to and including the year 200, etc.

Task
Given a year, return the century it is in.

Examples
1705 --> 18
1900 --> 19
1601 --> 17
2000 --> 20

Can you show me how to solve this using JavaScript
```

To which ChatGPT replied with:

```javascript
function century(year) {
  // Check if the year is exactly divisible by 100
  if (year % 100 === 0) {
    // If yes, return the century by dividing the year by 100
    return year / 100;
  } else {
    // If not, round up the year to the nearest century using Math.ceil() and divide by 100
    return Math.ceil(year / 100);
  }
}
```
Which if I paste into Codewars, actually passes first time!

Not bad.

**Solving it in C**

I then asked if it could rewrite this so that it would work in C and it responded with the following code:

```C
#include <stdio.h>
#include <math.h>

int century(int year) {
  // Check if the year is exactly divisible by 100
  if (year % 100 == 0) {
    // If yes, return the century by dividing the year by 100
    return year / 100;
  } else {
    // If not, round up the year to the nearest century using ceil() and divide by 100
    return ceil((double)year / 100);
  }
}
```

This passed all of the tests, also on its first attempt!

**Solving it in SQL**

```sql
CREATE FUNCTION century (year INT)
RETURNS INT
BEGIN
  -- Check if the year is exactly divisible by 100
  IF year % 100 = 0 THEN
    -- If yes, return the century by dividing the year by 100
    RETURN year / 100;
  ELSE
    -- If not, round up the year to the nearest century using CEILING() and divide by 100
    RETURN CEILING(year / 100.0);
  END IF;
END;
```
The above is the first attempt at solving this challenge using SQL and it failed the tests.

So that these challenges do not go on forever, I am going to limit each language to a maximum of 3 tries. 2 more to go in that case!

I then asked:

```bash
That solution returned a lot of syntax errors. I have pasted some of them below, do you think you could try and write a solution again using SQL.

PG::SyntaxError: ERROR:  syntax error at or near "BEGIN"
LINE 3: BEGIN
        ^
PG::SyntaxError: ERROR:  syntax error at or near "BEGIN"
LINE 3: BEGIN
        ^

If it helps, here are the test cases

items = DB[:years]

basic_tests = [
  [1705, 18],
  [1900, 19],
  [1601, 17],
  [2000, 20],
  [356, 4],
  [89, 1]
]

basic_tests.each do |x|
  items.insert(:yr => x[0])
end

results = run_sql.to_a

describe :basic_tests do
  basic_tests.each_with_index do |x, i|
    it "Test for year #{x[0]}" do
      expect(results[i][:century]).to eq x[1]
    end
  end
end
```

To which it replied with the following:

```sql
CREATE OR REPLACE FUNCTION century (year INT)
RETURNS INT AS $$
BEGIN
  -- Check if the year is exactly divisible by 100
  IF year % 100 = 0 THEN
    -- If yes, return the century by dividing the year by 100
    RETURN year / 100;
  ELSE
    -- If not, round up the year to the nearest century using CEILING() and divide by 100
    RETURN CEILING(year / 100.0);
  END IF;
END;
$$ LANGUAGE plpgsql;
```

Which also failed, down to are last attempt.

I told ChatGPT the following:

```bash
That also failed every single test case. Here is the error, can you try again with this information:

./spec/query_spec.rb:20:in `block (3 levels) in <top (required)>': undefined method `[]' for nil:NilClass (NoMethodError)
```

It then gave me this:

```sql
CREATE OR REPLACE FUNCTION century (year INT)
RETURNS INT AS $$
BEGIN
  -- Check if the year is exactly divisible by 100
  IF year % 100 = 0 THEN
    -- If yes, return the century by dividing the year by 100
    RETURN year / 100;
  ELSE
    -- If not, round up the year to the nearest century using CEILING() and divide by 100
    RETURN CEILING(year / 100.0);
  END IF;
END;
$$ LANGUAGE plpgsql;
```
Which sadly also failed.

Moving forward I think it may be the case that we only use JavaScript and C as it is not looking great for SQL at this moment in time!

I do wonder if the SQL dialect (Is that a thing) was correct and if that was indeed the issue but upon checking, it was for Postgres which ChatGPT seemed to have figured out.

Any tips on improving the SQL guidance would be appreciated and I would try again to use SQL in this little experiment.

_A few moments later_

After a discussion with a friend, it would seem that ChatGTP could easily solve the problem.

The issue was that I was asking in one continuous thread which meant it was trying to take a function written in C and write it in SQL.

When asking from scratch, it gave the following code:

```sql
SELECT CEILING(yr/100.0) AS century
FROM years
```

Which actually passes.

So SQL is back in the game and going forward, each language will be a fresh start in terms of questioning ChatGPT.