I'm using the early ProjectEuler problems as a way to get to know Factor. Already in the very first problem I don't find a satisfactory solution.
I can solve the division test with this
: 3or5divisible ( n -- ? ) [ 3 mod ] [ 5 mod ] bi * 0 = ;
But what I don't like is the repetition of the mod. Of course it's only two times, but another problem might need to check 200.
I tried with map, curry, bi, 2bi, bi#, arrays and plain stack values etc. I always get a stack underflow or an effect mismatch (when using map). I have have not yet found a way to see the results of my trials in the inspector.
How can I factor that mod out and have it applied to { 3 5 } or an equivalent stack?
Cool would be two variants e.g. of a mod3and5 (including effect specification); one that leaves 2 1 on the stack for input 11 and one that returns { 2 1 }.
I can only think of doing it this way, which removes one of the mods, but ends up adding a bi-curry# function.
: 3or5divisible ( n -- ? ) 3 5 [ mod ] bi-curry# bi * 0 = ;
I'm trying to update a working solution of incrementing one ID based on several conditions, so I was using the ROW() function without any issue. But now I'm trying to increment 2 different IDs based on selected option as shown in the screenshot below, where I've started the following so far:
=ARRAYFORMULA(IF(LEN(A2:A),COUNTIFS(A2:A, A2:A, ROW(A2:A), "<="&ROW(A2:A),A2:A,"Option 2"),))
Can anyone bring some light on this scenario: thanks
Link of spreadsheet illustrating my situation: here
You have to first check if the value is Option 1/Option 2 or not. A way to do this without using OR (which can't be iterated over an array) is this:
IF(A2:A="Option 1",0,1)*IF(A2:A="Option 2",0,1)
Next, you can wrap this into another IF so that the returned value depends on whether the previous condition is true. So, if option is not 1 nor 2, the corresponding value should result from the count of all the previous values which are not 1 or 2. So the COUNTIFS should check if the option is not 1 nor 2. Something like this:
29999 + COUNTIFS(A2:A,"<>Option 1",A2:A,"<>Option 2",ROW(A2:A), "<="&ROW(A2:A))
Finally, if the option is 1 or 2, the returned value should result from hte count of all previous 1 and 2 values. Since that's an OR condition, you have to sum two different COUNTIFS, one for option 1 and one for 2. Could be like this:
9999 + COUNTIFS(A2:A,"=Option 1",ROW(A2:A), "<="&ROW(A2:A)) + COUNTIFS(A2:A,"=Option 2",ROW(A2:A), "<="&ROW(A2:A))
Putting it all together, it could be like this:
=ARRAYFORMULA(IF(LEN(A2:A),IF(IF(A2:A="Option 1",0,1)*IF(A2:A="Option 2",0,1),
29999 + COUNTIFS(A2:A,"<>Option 1",A2:A,"<>Option 2",ROW(A2:A), "<="&ROW(A2:A)),
9999 + COUNTIFS(A2:A,"=Option 1",ROW(A2:A), "<="&ROW(A2:A)) + COUNTIFS(A2:A,"=Option 2",ROW(A2:A), "<="&ROW(A2:A))),""))
slight alternative:
=ARRAYFORMULA(IF(A2:A="",,IF(REGEXMATCH(A2:A, H2&"$|"&H3&"$"),
9999+COUNTIFS(REGEXMATCH(A2:A, H2&"$|"&H3&"$"),
REGEXMATCH(A2:A, H2&"$|"&H3&"$"), ROW(A2:A), "<="&ROW(A2:A)),
29999+COUNTIFS(A2:A, "<>"&H2, A2:A, "<>"&H3, ROW(A2:A), "<="&ROW(A2:A)))))
I have a table and want to convert a column of type decimal to an integer based on a condition. I need to do this as performant as possible.
My currently working query looks like this:
select *, (case when C_CUSTKEY < 20 then 1 else 0 end) as bit
from TPCH.CUSTOMER
However I'm trying to improve this. Is it possible to do the conversion on the fly, e.g. something like this:
select *, cast((C_CUSTKEY < 20) as integer) as bit
from TPCH.CUSTOMER
Or even for a simpler version like:
select *, (C_CUSTKEY < 20) as bit
from TPCH.CUSTOMER
No matter what functionality I use, I always get the following error:
sql syntax error: incorrect syntax near "<"
Update 1
So for better understanding an actual usecase of what I want to do is as following:
select ( (case when col1 < x then 1 else 0 end)
+ (case when col2 > y then 2 else 0 end) ) as bitset
from TPCH.CUSTOMER
In general there can be a large number of 'case when' expressions (>100).
Now the first problem is that the expression is very slow and I need to improve performance so I wanted to know if its possible to to the conversion on the fly smth like 2 * to_int(col2 > y) but I cannot find a way to do this.
Second problem is when I have many 'case when' expressions then I get the following error: SQL internal parse tree depth exceeds its maximum: parse tree depth exceeds its maximum:255
Not quite sure about the use case here.
Generally speaking, you cannot have a different data type for the same column at the same time. That's a fundamental constraint of the relational data model.
If however, the requirement merely is to have an indicator for "value in C_CUSTKEY < 20" then using the CASE statement is a straightforward way to do this.
In order to avoid this evaluation at query time, you could create a calculated column for this.
alter table TPCH.CUSTOMER add ("BIT" integer
generated always as
case
when ("C_CUSTKEY" < 20)
then 1
else 0
end);
Concerning the syntax errors: well, you're just not using the correct syntax. Check the example above for a correctly working example.
I have a dataset of actions doing over time, an attribute 'Hour' ( contains values from 0 ->23 ). Now I want to create another attribute, say 'PartOfDay', which group 24 hours into 4 parts. For tuples have 'Hour' value of 0 to 5, then the 'PartOfDay' value should be 1; if 'Hour' value in [6,11], then the 'PartOfDay' value should be 2;...How can I do?
The codes would do this:
train['PartOfDay']=1
train.loc[(train.Hour>=6) & (train.hour<=11),'PartOfDay']=2
train.loc[(train.Hour>=12) & (train.hour<=17),'PartOfDay']=3
train.loc[(train.Hour>=18) & (train.hour<=23),'PartOfDay']=4
but it seems not so beautiful, I would like to know a more decent one if possible
Thank you for all your supports!!
While it is not clear what train.loc represents, a general approach to your problem is to use modulus function to set the RHS:
1 + int(train.Hour / 6)
I have a query that's basically "count all the items of type X, and return the items that exist more than once, along with their counts". Right now I have this:
Item.objects.annotate(type_count=models.Count("type")).filter(type_count__gt=1).order_by("-type_count")
but it returns nothing (the count is 1 for all items). What am I doing wrong?
Ideally, it should get the following:
Type
----
1
1
2
3
3
3
and return:
Type, Count
-----------
1 2
3 3
In order to count the number of occurrences of each type, you have to group by the type field. In Django this is done by using values to get just that field. So, this should work:
Item.objects.values('group').annotate(
type_count=models.Count("type")
).filter(type_count__gt=1).order_by("-type_count")
It's logical error ;)
type_count__gt=1 means type_count > 1 so if the count == 1 it won't be displayed :)
use type_count__gte=1 instead - it means type_count >= 1 :)